Index: trunk/CLHEP/Units/PhysicalConstants.h
===================================================================
--- trunk/CLHEP/Units/PhysicalConstants.h	(revision 4)
+++ trunk/CLHEP/Units/PhysicalConstants.h	(revision 4)
@@ -0,0 +1,143 @@
+// -*- C++ -*-
+// $Id: PhysicalConstants.h,v 1.1 2008-06-04 14:14:54 demin Exp $
+// ----------------------------------------------------------------------
+// HEP coherent Physical Constants
+//
+// This file has been provided by Geant4 (simulation toolkit for HEP).
+//
+// The basic units are :
+//  		millimeter  
+// 		nanosecond  
+// 		Mega electron Volt  
+// 		positon charge 
+// 		degree Kelvin
+//              amount of substance (mole)
+//              luminous intensity (candela)
+// 		radian  
+//              steradian 
+//
+// Below is a non exhaustive list of Physical CONSTANTS,
+// computed in the Internal HEP System Of Units.
+//
+// Most of them are extracted from the Particle Data Book :
+//        Phys. Rev. D  volume 50 3-1 (1994) page 1233
+// 
+//        ...with a meaningful (?) name ...
+//
+// You can add your own constants.
+//
+// Author: M.Maire
+//
+// History:
+//
+// 23.02.96 Created
+// 26.03.96 Added constants for standard conditions of temperature
+//          and pressure; also added Gas threshold.
+
+#ifndef HEP_PHYSICAL_CONSTANTS_H
+#define HEP_PHYSICAL_CONSTANTS_H
+
+#include "CLHEP/Units/defs.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+
+namespace CLHEP {
+
+//
+//
+//
+static const double     pi  = 3.14159265358979323846;
+static const double  twopi  = 2*pi;
+static const double halfpi  = pi/2;
+static const double     pi2 = pi*pi;
+
+//
+// 
+//
+static const double Avogadro = 6.0221367e+23/mole;
+
+//
+// c   = 299.792458 mm/ns
+// c^2 = 898.7404 (mm/ns)^2 
+//
+static const double c_light   = 2.99792458e+8 * m/s;
+static const double c_squared = c_light * c_light;
+
+//
+// h     = 4.13566e-12 MeV*ns
+// hbar  = 6.58212e-13 MeV*ns
+// hbarc = 197.32705e-12 MeV*mm
+//
+static const double h_Planck      = 6.6260755e-34 * joule*s;
+static const double hbar_Planck   = h_Planck/twopi;
+static const double hbarc         = hbar_Planck * c_light;
+static const double hbarc_squared = hbarc * hbarc;
+
+//
+//
+//
+static const double electron_charge = - eplus; // see SystemOfUnits.h
+static const double e_squared = eplus * eplus;
+
+//
+// amu_c2 - atomic equivalent mass unit
+// amu    - atomic mass unit
+//
+static const double electron_mass_c2 = 0.51099906 * MeV;
+static const double   proton_mass_c2 = 938.27231 * MeV;
+static const double  neutron_mass_c2 = 939.56563 * MeV;
+static const double           amu_c2 = 931.49432 * MeV;
+static const double              amu = amu_c2/c_squared;
+
+//
+// permeability of free space mu0    = 2.01334e-16 Mev*(ns*eplus)^2/mm
+// permittivity of free space epsil0 = 5.52636e+10 eplus^2/(MeV*mm)
+//
+static const double mu0      = 4*pi*1.e-7 * henry/m;
+static const double epsilon0 = 1./(c_squared*mu0);
+
+//
+// electromagnetic coupling = 1.43996e-12 MeV*mm/(eplus^2)
+//
+static const double elm_coupling           = e_squared/(4*pi*epsilon0);
+static const double fine_structure_const   = elm_coupling/hbarc;
+static const double classic_electr_radius  = elm_coupling/electron_mass_c2;
+static const double electron_Compton_length = hbarc/electron_mass_c2;
+static const double Bohr_radius = electron_Compton_length/fine_structure_const;
+
+static const double alpha_rcl2 = fine_structure_const
+                                   *classic_electr_radius
+                                   *classic_electr_radius;
+
+static const double twopi_mc2_rcl2 = twopi*electron_mass_c2
+                                             *classic_electr_radius
+                                             *classic_electr_radius;
+//
+//
+//
+static const double k_Boltzmann = 8.617385e-11 * MeV/kelvin;
+
+//
+//
+//
+static const double STP_Temperature = 273.15*kelvin;
+static const double STP_Pressure    = 1.*atmosphere;
+static const double kGasThreshold   = 10.*mg/cm3;
+
+//
+//
+//
+static const double universe_mean_density = 1.e-25*g/cm3;
+
+}  // namespace CLHEP
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_PHYSICAL_CONSTANTS_H */
+
+
+
+
+
Index: trunk/CLHEP/Units/SystemOfUnits.h
===================================================================
--- trunk/CLHEP/Units/SystemOfUnits.h	(revision 4)
+++ trunk/CLHEP/Units/SystemOfUnits.h	(revision 4)
@@ -0,0 +1,293 @@
+// -*- C++ -*-
+// $Id: SystemOfUnits.h,v 1.1 2008-06-04 14:14:54 demin Exp $
+// ----------------------------------------------------------------------
+// HEP coherent system of Units
+//
+// This file has been provided to CLHEP by Geant4 (simulation toolkit for HEP).
+//
+// The basic units are :
+//  millimeter              (millimeter)
+// nanosecond              (nanosecond)
+// Mega electron Volt      (MeV)
+// positron charge         (eplus)
+// degree Kelvin           (kelvin)
+//              the amount of substance (mole)
+//              luminous intensity      (candela)
+// radian                  (radian)
+//              steradian               (steradian)
+//
+// Below is a non exhaustive list of derived and pratical units
+// (i.e. mostly the SI units).
+// You can add your own units.
+//
+// The SI numerical value of the positron charge is defined here,
+// as it is needed for conversion factor : positron charge = e_SI (coulomb)
+//
+// The others physical constants are defined in the header file :
+//PhysicalConstants.h
+//
+// Authors: M.Maire, S.Giani
+//
+// History:
+//
+// 06.02.96   Created.
+// 28.03.96   Added miscellaneous constants.
+// 05.12.97   E.Tcherniaev: Redefined pascal (to avoid warnings on WinNT)
+// 20.05.98   names: meter, second, gram, radian, degree
+//            (from Brian.Lasiuk@yale.edu (STAR)). Added luminous units.
+// 05.08.98   angstrom, picobarn, microsecond, picosecond, petaelectronvolt
+// 01.03.01   parsec    
+// 31.01.06   kilogray, milligray, microgray    
+
+#ifndef HEP_SYSTEM_OF_UNITS_H
+#define HEP_SYSTEM_OF_UNITS_H
+
+#include "CLHEP/Units/defs.h"
+
+namespace CLHEP {
+
+  // 
+  // Length [L]
+  //
+  static const double millimeter  = 1.;                        
+  static const double millimeter2 = millimeter*millimeter;
+  static const double millimeter3 = millimeter*millimeter*millimeter;
+
+  static const double centimeter  = 10.*millimeter;   
+  static const double centimeter2 = centimeter*centimeter;
+  static const double centimeter3 = centimeter*centimeter*centimeter;
+
+  static const double meter  = 1000.*millimeter;                  
+  static const double meter2 = meter*meter;
+  static const double meter3 = meter*meter*meter;
+
+  static const double kilometer = 1000.*meter;                   
+  static const double kilometer2 = kilometer*kilometer;
+  static const double kilometer3 = kilometer*kilometer*kilometer;
+
+  static const double parsec = 3.0856775807e+16*meter;
+
+  static const double micrometer = 1.e-6 *meter;             
+  static const double  nanometer = 1.e-9 *meter;
+  static const double  angstrom  = 1.e-10*meter;
+  static const double  fermi     = 1.e-15*meter;
+
+  static const double      barn = 1.e-28*meter2;
+  static const double millibarn = 1.e-3 *barn;
+  static const double microbarn = 1.e-6 *barn;
+  static const double  nanobarn = 1.e-9 *barn;
+  static const double  picobarn = 1.e-12*barn;
+
+  // symbols
+  static const double nm  = nanometer;                        
+  static const double um  = micrometer;                        
+
+  static const double mm  = millimeter;                        
+  static const double mm2 = millimeter2;
+  static const double mm3 = millimeter3;
+
+  static const double cm  = centimeter;   
+  static const double cm2 = centimeter2;
+  static const double cm3 = centimeter3;
+
+  static const double m  = meter;                  
+  static const double m2 = meter2;
+  static const double m3 = meter3;
+
+  static const double km  = kilometer;                   
+  static const double km2 = kilometer2;
+  static const double km3 = kilometer3;
+
+  static const double pc = parsec;
+
+  //
+  // Angle
+  //
+  static const double radian      = 1.;                  
+  static const double milliradian = 1.e-3*radian;
+  static const double degree = (3.14159265358979323846/180.0)*radian;
+
+  static const double   steradian = 1.;
+  
+  // symbols
+  static const double rad  = radian;
+  static const double mrad = milliradian;
+  static const double sr   = steradian;
+  static const double deg  = degree;
+
+  //
+  // Time [T]
+  //
+  static const double nanosecond  = 1.;
+  static const double second      = 1.e+9 *nanosecond;
+  static const double millisecond = 1.e-3 *second;
+  static const double microsecond = 1.e-6 *second;
+  static const double  picosecond = 1.e-12*second;
+
+  static const double hertz = 1./second;
+  static const double kilohertz = 1.e+3*hertz;
+  static const double megahertz = 1.e+6*hertz;
+
+  // symbols
+  static const double ns = nanosecond;
+  static const double  s = second;
+  static const double ms = millisecond;
+
+  //
+  // Electric charge [Q]
+  //
+  static const double eplus = 1. ;// positron charge
+  static const double e_SI  = 1.60217733e-19;// positron charge in coulomb
+  static const double coulomb = eplus/e_SI;// coulomb = 6.24150 e+18 * eplus
+
+  //
+  // Energy [E]
+  //
+  static const double megaelectronvolt = 1. ;
+  static const double     electronvolt = 1.e-6*megaelectronvolt;
+  static const double kiloelectronvolt = 1.e-3*megaelectronvolt;
+  static const double gigaelectronvolt = 1.e+3*megaelectronvolt;
+  static const double teraelectronvolt = 1.e+6*megaelectronvolt;
+  static const double petaelectronvolt = 1.e+9*megaelectronvolt;
+
+  static const double joule = electronvolt/e_SI;// joule = 6.24150 e+12 * MeV
+
+  // symbols
+  static const double MeV = megaelectronvolt;
+  static const double  eV = electronvolt;
+  static const double keV = kiloelectronvolt;
+  static const double GeV = gigaelectronvolt;
+  static const double TeV = teraelectronvolt;
+  static const double PeV = petaelectronvolt;
+
+  //
+  // Mass [E][T^2][L^-2]
+  //
+  static const double  kilogram = joule*second*second/(meter*meter);   
+  static const double      gram = 1.e-3*kilogram;
+  static const double milligram = 1.e-3*gram;
+
+  // symbols
+  static const double  kg = kilogram;
+  static const double   g = gram;
+  static const double  mg = milligram;
+
+  //
+  // Power [E][T^-1]
+  //
+  static const double watt = joule/second;// watt = 6.24150 e+3 * MeV/ns
+
+  //
+  // Force [E][L^-1]
+  //
+  static const double newton = joule/meter;// newton = 6.24150 e+9 * MeV/mm
+
+  //
+  // Pressure [E][L^-3]
+  //
+#define pascal hep_pascal                          // a trick to avoid warnings 
+  static const double hep_pascal = newton/m2;   // pascal = 6.24150 e+3 * MeV/mm3
+  static const double bar        = 100000*pascal; // bar    = 6.24150 e+8 * MeV/mm3
+  static const double atmosphere = 101325*pascal; // atm    = 6.32420 e+8 * MeV/mm3
+
+  //
+  // Electric current [Q][T^-1]
+  //
+  static const double      ampere = coulomb/second; // ampere = 6.24150 e+9 * eplus/ns
+  static const double milliampere = 1.e-3*ampere;
+  static const double microampere = 1.e-6*ampere;
+  static const double  nanoampere = 1.e-9*ampere;
+
+  //
+  // Electric potential [E][Q^-1]
+  //
+  static const double megavolt = megaelectronvolt/eplus;
+  static const double kilovolt = 1.e-3*megavolt;
+  static const double     volt = 1.e-6*megavolt;
+
+  //
+  // Electric resistance [E][T][Q^-2]
+  //
+  static const double ohm = volt/ampere;// ohm = 1.60217e-16*(MeV/eplus)/(eplus/ns)
+
+  //
+  // Electric capacitance [Q^2][E^-1]
+  //
+  static const double farad = coulomb/volt;// farad = 6.24150e+24 * eplus/Megavolt
+  static const double millifarad = 1.e-3*farad;
+  static const double microfarad = 1.e-6*farad;
+  static const double  nanofarad = 1.e-9*farad;
+  static const double  picofarad = 1.e-12*farad;
+
+  //
+  // Magnetic Flux [T][E][Q^-1]
+  //
+  static const double weber = volt*second;// weber = 1000*megavolt*ns
+
+  //
+  // Magnetic Field [T][E][Q^-1][L^-2]
+  //
+  static const double tesla     = volt*second/meter2;// tesla =0.001*megavolt*ns/mm2
+
+  static const double gauss     = 1.e-4*tesla;
+  static const double kilogauss = 1.e-1*tesla;
+
+  //
+  // Inductance [T^2][E][Q^-2]
+  //
+  static const double henry = weber/ampere;// henry = 1.60217e-7*MeV*(ns/eplus)**2
+
+  //
+  // Temperature
+  //
+  static const double kelvin = 1.;
+
+  //
+  // Amount of substance
+  //
+  static const double mole = 1.;
+
+  //
+  // Activity [T^-1]
+  //
+  static const double becquerel = 1./second ;
+  static const double curie = 3.7e+10 * becquerel;
+
+  //
+  // Absorbed dose [L^2][T^-2]
+  //
+  static const double      gray = joule/kilogram ;
+  static const double  kilogray = 1.e+3*gray;
+  static const double milligray = 1.e-3*gray;
+  static const double microgray = 1.e-6*gray;
+
+  //
+  // Luminous intensity [I]
+  //
+  static const double candela = 1.;
+
+  //
+  // Luminous flux [I]
+  //
+  static const double lumen = candela*steradian;
+
+  //
+  // Illuminance [I][L^-2]
+  //
+  static const double lux = lumen/meter2;
+
+  //
+  // Miscellaneous
+  //
+  static const double perCent     = 0.01 ;
+  static const double perThousand = 0.001;
+  static const double perMillion  = 0.000001;
+
+}  // namespace CLHEP
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_SYSTEM_OF_UNITS_H */
Index: trunk/CLHEP/Units/defs.h
===================================================================
--- trunk/CLHEP/Units/defs.h	(revision 4)
+++ trunk/CLHEP/Units/defs.h	(revision 4)
@@ -0,0 +1,42 @@
+/* Units/defs.h.  Generated by configure.  */
+/* Units/defs.h.in.  Generated from configure.in by autoheader.  */
+
+#ifndef UNITS_DEFS_H
+#define UNITS_DEFS_H
+
+/* Name of package */
+#ifndef PACKAGE
+#define PACKAGE "Units"
+#endif
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT "http://savannah.cern.ch/projects/clhep/"
+#endif
+
+/* Define to the full name of this package. */
+#ifndef PACKAGE_NAME
+#define PACKAGE_NAME "CLHEP Units"
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef PACKAGE_STRING
+#define PACKAGE_STRING "CLHEP Units 2.0.3.0"
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef PACKAGE_TARNAME
+#define PACKAGE_TARNAME "Units"
+#endif
+
+/* Define to the version of this package. */
+#ifndef PACKAGE_VERSION
+#define PACKAGE_VERSION "2.0.3.0"
+#endif
+
+/* Version number of package */
+#ifndef VERSION
+#define VERSION "2.0.3.0"
+#endif
+
+#endif  // UNITS_DEFS_H
Index: trunk/CLHEP/Vector/AxisAngle.h
===================================================================
--- trunk/CLHEP/Vector/AxisAngle.h	(revision 4)
+++ trunk/CLHEP/Vector/AxisAngle.h	(revision 4)
@@ -0,0 +1,122 @@
+#ifndef HEP_AXISANGLE_H
+#define HEP_AXISANGLE_H
+
+// ----------------------------------------------------------------------
+//
+// AxisAngle.h - provide HepAxisAngle class
+//
+// History:
+//   23-Jan-1998  WEB  Initial draft
+//   15-Jun-1998  WEB  Added namespace support
+//   02-May-2000  WEB  No global using
+//   27-Jul-2000  MF   CLHEP version
+//
+// ----------------------------------------------------------------------
+
+
+#ifndef HEP_THREEVECTOR_H
+  #include "CLHEP/Vector/ThreeVector.h"
+#endif
+
+#include <iostream>
+#include "CLHEP/Vector/defs.h" 
+
+
+namespace CLHEP {
+
+
+// Declarations of classes and global methods
+class HepAxisAngle;
+std::ostream & operator<<( std::ostream & os, const HepAxisAngle & aa );
+std::istream & operator>>( std::istream & is,       HepAxisAngle & aa );
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepAxisAngle {
+
+public:
+  typedef double Scalar;
+
+protected:
+  typedef HepAxisAngle AA;         // just an abbreviation
+  static Scalar tolerance;      // to determine relative nearness
+
+public:
+
+  // ----------  Constructors:
+  inline HepAxisAngle();
+  inline HepAxisAngle( const Hep3Vector axis, Scalar delta );
+
+  // ----------  Destructor, copy constructor, assignment:
+  // use C++ defaults
+
+  // ----------  Accessors:
+
+public:
+  inline Hep3Vector            getAxis() const;
+  inline Hep3Vector            axis() const;
+  inline AA &                  setAxis( const Hep3Vector axis );
+
+  inline double             getDelta() const;
+  inline double             delta() const ;
+  inline AA &                  setDelta( Scalar delta );
+
+  inline AA & set( const Hep3Vector axis, Scalar delta );
+
+  // ----------  Operations:
+
+  //   comparisons:
+  inline int  compare   ( const AA & aa ) const;
+
+  inline bool operator==( const AA & aa ) const;
+  inline bool operator!=( const AA & aa ) const;
+  inline bool operator< ( const AA & aa ) const;
+  inline bool operator<=( const AA & aa ) const;
+  inline bool operator> ( const AA & aa ) const;
+  inline bool operator>=( const AA & aa ) const;
+
+  //   relative comparison:
+  inline static double getTolerance();
+  inline static double setTolerance( Scalar tol );
+
+protected:
+    double distance( const HepAxisAngle & aa ) const;
+public:
+
+  bool isNear ( const AA & aa, Scalar epsilon = tolerance ) const;
+  double  howNear( const AA & aa ) const;
+
+  // ----------  I/O:
+
+  friend std::ostream & operator<<( std::ostream & os, const AA & aa );
+  friend std::istream & operator>>( std::istream & is,       AA & aa );
+
+private:
+  Hep3Vector axis_;  // Note:  After construction, this is always of mag 1
+  double  delta_;
+
+};  // HepAxisAngle
+
+
+}  // namespace CLHEP
+
+
+namespace zmpv  {
+
+  typedef CLHEP::HepAxisAngle AxisAngle;
+
+}  // namespace zmpv
+
+
+#define AXISANGLE_ICC
+#include "CLHEP/Vector/AxisAngle.icc"
+#undef AXISANGLE_ICC
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif  // HEP_AXISANGLE_H
Index: trunk/CLHEP/Vector/AxisAngle.icc
===================================================================
--- trunk/CLHEP/Vector/AxisAngle.icc	(revision 4)
+++ trunk/CLHEP/Vector/AxisAngle.icc	(revision 4)
@@ -0,0 +1,119 @@
+#ifndef AXISANGLE_ICC
+#error "AxisAngle.icc included without AxisAngle.h"
+#endif
+
+
+// ----------------------------------------------------------------------
+//
+// AxisAngle.icc
+//
+// History:
+//   23-Jan-1998  WEB  Initial draft
+//   12-Mar-1998  WEB  Gave default constructor proper default values
+//   13-Mar-1998  WEB  Corrected setDelta; simplified compare()
+//   17-Jun-1998  WEB  Added namespace support
+//   26-Jul-2000  MF   CLHEP version
+//
+// ----------------------------------------------------------------------
+
+namespace CLHEP {
+
+inline HepAxisAngle::HepAxisAngle() :
+  axis_( Hep3Vector(0,0,1) ), delta_( 0.0 )
+{}  // HepAxisAngle::HepAxisAngle()
+
+inline HepAxisAngle::HepAxisAngle( const Hep3Vector axis, Scalar delta ) :
+  axis_( axis.unit() ), delta_( delta )
+{}  // HepAxisAngle::HepAxisAngle()
+
+
+inline Hep3Vector HepAxisAngle::getAxis() const {
+  return  axis_;
+}  // HepAxisAngle::getAxis()
+
+inline Hep3Vector HepAxisAngle::axis() const {
+  return  axis_;
+}  // HepAxisAngle::axis()
+
+
+inline HepAxisAngle & HepAxisAngle::setAxis( const Hep3Vector axis ) {
+  axis_ = axis.unit();
+  return  *this;
+}  // HepAxisAngle::setAxis()
+
+
+inline double HepAxisAngle::getDelta() const {
+  return  delta_;
+}  // HepAxisAngle::getDelta()
+
+inline double HepAxisAngle::delta() const {
+  return  delta_;
+}  // HepAxisAngle::delta()
+
+
+inline HepAxisAngle & HepAxisAngle::setDelta( Scalar delta ) {
+  delta_ = delta;
+  return  *this;
+}  // HepAxisAngle::setDelta()
+
+
+inline HepAxisAngle & HepAxisAngle::set( const Hep3Vector axis, Scalar delta ) {
+  axis_ = axis.unit();
+  delta_ = delta;
+  return  *this;
+}  // HepAxisAngle::set()
+
+
+inline int HepAxisAngle::compare( const AA & aa ) const {
+
+  return  delta_ < aa.delta_  ?  -1
+       :  delta_ > aa.delta_  ?  +1
+       :  axis_  < aa.axis_   ?  -1
+       :  axis_  > aa.axis_   ?  +1
+       :                          0;
+
+}  // HepAxisAngle::compare()
+
+
+inline bool HepAxisAngle::operator==( const AA & aa ) const {
+  return  ( compare( aa ) == 0 );
+}  // HepAxisAngle::operator==()
+
+
+inline bool HepAxisAngle::operator!=( const AA & aa ) const {
+  return  ( compare( aa ) != 0 );
+}  // HepAxisAngle::operator!=()
+
+
+inline bool HepAxisAngle::operator<( const AA & aa ) const {
+  return  ( compare( aa ) < 0 );
+}  // HepAxisAngle::operator<()
+
+
+inline bool HepAxisAngle::operator<=( const AA & aa ) const {
+  return  ( compare( aa ) <= 0 );
+}  // HepAxisAngle::operator<=()
+
+
+inline bool HepAxisAngle::operator>( const AA & aa ) const {
+  return  ( compare( aa ) > 0 );
+}  // HepAxisAngle::operator>()
+
+
+inline bool HepAxisAngle::operator>=( const AA & aa ) const {
+  return  ( compare( aa ) >= 0 );
+}  // HepAxisAngle::operator>=()
+
+
+inline double HepAxisAngle::getTolerance() {
+  return tolerance;
+}  // HepAxisAngle::getTolerance()
+
+
+inline double HepAxisAngle::setTolerance( Scalar tol ) {
+  Scalar oldTolerance( tolerance );
+  tolerance = tol;
+  return oldTolerance;
+}  // HepAxisAngle::setTolerance()
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/Boost.h
===================================================================
--- trunk/CLHEP/Vector/Boost.h	(revision 4)
+++ trunk/CLHEP/Vector/Boost.h	(revision 4)
@@ -0,0 +1,253 @@
+// -*- C++ -*-
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepBoost class for performing specialized
+// Lorentz transformations which are pure boosts on objects of the
+// HepLorentzVector class.
+//
+// HepBoost is a concrete implementation of Hep4RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// LorentzVector.h LorentzRotation.h 
+//  BoostX.h BoostY.h BoostZ.h 
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_BOOST_H
+#define HEP_BOOST_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/BoostX.h"
+#include "CLHEP/Vector/BoostY.h"
+#include "CLHEP/Vector/BoostZ.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP {
+
+// Declarations of classes and global methods
+class HepBoost;
+inline HepBoost inverseOf ( const HepBoost & lt );
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepBoost {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepBoost();
+  // Default constructor. Gives a boost of 0.  
+
+  inline HepBoost(const HepBoost & m);
+  // Copy constructor.
+
+  inline HepBoost & operator = (const HepBoost & m);
+  // Assignment.
+
+         HepBoost & set (double betaX, double betaY, double betaZ);
+  inline HepBoost       (double betaX, double betaY, double betaZ);
+  // Constructor from three components of beta vector
+
+         HepBoost & set (const HepRep4x4Symmetric & m);
+  inline HepBoost       (const HepRep4x4Symmetric & m);
+  // Constructor from symmetric HepRep4x4
+
+         HepBoost & set (Hep3Vector direction, double beta);
+  inline HepBoost       (Hep3Vector direction, double beta);
+  // Constructor from a three vector direction and the magnitude of beta
+
+         HepBoost & set (const Hep3Vector & boost);
+  inline HepBoost       (const Hep3Vector & boost);
+  // Constructor from a 3-vector of less than unit length
+
+  inline HepBoost & set (const HepBoostX & boost);
+  inline HepBoost & set (const HepBoostY & boost);
+  inline HepBoost & set (const HepBoostZ & boost);
+  inline HepBoost       (const HepBoostX & boost);
+  inline HepBoost       (const HepBoostY & boost);
+  inline HepBoost       (const HepBoostZ & boost);
+
+  // ----------  Accessors:
+
+  inline double  beta()  const;
+  inline double  gamma() const;
+  inline Hep3Vector boostVector() const;
+  inline Hep3Vector getDirection() const;
+  inline Hep3Vector direction() const;
+
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double xt() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double yt() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  inline double tt() const;
+  // Elements of the matrix.
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  inline HepLorentzVector col4() const;
+  // orthosymplectic column vectors
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  inline HepLorentzVector row4() const;
+  // orthosymplectic row vectors
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation.
+
+  inline HepRep4x4Symmetric rep4x4Symmetric() const;
+  //   Symmetric 4x4 representation.
+
+  // ----------  Decomposition:
+
+  void decompose (HepRotation  & rotation, HepBoost   & boost) const;
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  // Find R and B such that L = R*B -- trivial, since R is identity
+
+  void decompose (HepBoost   & boost, HepRotation  & rotation) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  // Find R and B such that L = B*R -- trivial, since R is identity
+
+  // ----------  Comparisons:
+
+  inline int compare( const HepBoost & b  ) const;
+  // Dictionary-order comparison, in order tt,zt,zz,yt,yz,yy,xt,xz,xy,xx
+  // Used in operator<, >, <=, >=
+
+  inline bool operator == (const HepBoost & b) const;
+  inline bool operator != (const HepBoost & b) const;
+  inline bool operator <= (const HepBoost & b) const;
+  inline bool operator >= (const HepBoost & b) const;
+  inline bool operator <  (const HepBoost & b) const;
+  inline bool operator >  (const HepBoost & b) const;
+  // Comparisons.
+
+  inline bool isIdentity() const;
+  // Returns true if a null boost.
+
+  inline  double distance2( const HepBoost  & b  ) const;
+  inline  double distance2( const HepBoostX & bx ) const;
+  inline  double distance2( const HepBoostY & by ) const;
+  inline  double distance2( const HepBoostZ & bz ) const;
+  // Defined as the distance2 between the vectors (gamma*betaVector)
+
+  double distance2( const HepRotation & r  ) const;
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // Distance between this and other sorts of transformations
+
+  inline double howNear(   const HepBoost & b ) const;
+  inline bool isNear(   const HepBoost & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  double howNear( const HepRotation & r  ) const;
+  double howNear( const HepLorentzRotation & lt  ) const;
+
+  bool isNear( const HepRotation & r, 
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepLorentzRotation & lt, 
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const;
+  // (beta*gamma)^2
+
+  void rectify();
+  // set as an exact boost, based on the timelike part of the boost matrix.
+
+  // ---------- Application:
+
+  inline HepLorentzVector operator()( const HepLorentzVector & p ) const;
+  // Transform a Lorentz Vector.             
+
+  inline HepLorentzVector operator* ( const HepLorentzVector & p ) const;
+  // Multiplication with a Lorentz Vector.
+
+  // ---------- Operations in the group of 4-Rotations
+
+  HepLorentzRotation operator * (const HepBoost & b) const;
+  HepLorentzRotation operator * (const HepRotation & r) const;
+  HepLorentzRotation operator * (const HepLorentzRotation & lt) const;
+  // Product of two Lorentz Rotations (this) * lt - matrix multiplication  
+  // Notice that the product of two pure boosts is no longer a pure boost
+
+  inline HepBoost inverse() const;
+  // Return the inverse.
+
+  inline friend HepBoost inverseOf ( const HepBoost & lt );
+  // global methods to invert.
+
+  inline HepBoost & invert();
+  // Inverts the Boost matrix.
+
+  // ---------- I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output form is (bx, by, bz) 
+
+  // ---------- Tolerance              
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  inline HepLorentzVector vectorMultiplication 
+					( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  HepLorentzRotation matrixMultiplication (const HepRep4x4 & m) const;
+  HepLorentzRotation matrixMultiplication (const HepRep4x4Symmetric & m) const;
+
+  inline HepBoost
+       (double xx, double xy, double xz, double xt,
+		   double yy, double yz, double yt,
+			      double zz, double zt,
+					 double tt);
+  // Protected constructor.
+  // DOES NOT CHECK FOR VALIDITY AS A LORENTZ BOOST.
+
+  inline void setBoost(double bx, double by, double bz);
+
+  HepRep4x4Symmetric rep_;
+
+};  // HepBoost
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepBoost& b ) {return b.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/Boost.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_BOOST_H */
Index: trunk/CLHEP/Vector/Boost.icc
===================================================================
--- trunk/CLHEP/Vector/Boost.icc	(revision 4)
+++ trunk/CLHEP/Vector/Boost.icc	(revision 4)
@@ -0,0 +1,289 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepBoost class
+//
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+inline HepBoost::HepBoost() : rep_() {}
+
+inline HepBoost::HepBoost(const HepBoost & m) : rep_(m.rep_) {}
+
+inline HepBoost & HepBoost::operator = (const HepBoost & m) { 
+  rep_ = m.rep_; 
+  return *this;
+}
+
+inline HepBoost::HepBoost(double betaX, double betaY, double betaZ) 
+{
+  set(betaX, betaY, betaZ);
+}
+
+inline HepBoost::HepBoost(const HepRep4x4Symmetric & m) : rep_(m) {}
+
+inline HepBoost::HepBoost(Hep3Vector direction, double beta) 
+{
+  double length = direction.mag();
+  if (length==0) {
+    ZMthrowC ( ZMxpvZeroVector("HepBoost constructed using a zero vector as direction") );
+    set(0,0,0);
+  }
+  set(beta*direction.x()/length,
+      beta*direction.y()/length,
+      beta*direction.z()/length);
+}
+
+inline HepBoost::HepBoost(const Hep3Vector & boost) 
+{
+  set(boost.x(), boost.y(), boost.z());
+}
+
+inline HepBoost::HepBoost(const HepBoostX & boost) {set(boost.boostVector());}
+inline HepBoost::HepBoost(const HepBoostY & boost) {set(boost.boostVector());}
+inline HepBoost::HepBoost(const HepBoostZ & boost) {set(boost.boostVector());}
+inline HepBoost & HepBoost::set(const HepBoostX & boost) 
+					    {return set(boost.boostVector());}
+inline HepBoost & HepBoost::set(const HepBoostY & boost)
+					    {return set(boost.boostVector());}
+inline HepBoost & HepBoost::set(const HepBoostZ & boost)
+					    {return set(boost.boostVector());}
+
+// - Protected method:
+inline HepBoost::HepBoost ( 
+  double xx, double xy, double xz, double xt,
+  		double yy, double yz, double yt,
+  			      double zz, double zt,
+  					    double tt) :
+	  rep_ ( xx, xy, xz, xt, yy, yz, yt, zz, zt, tt ) {}	
+
+// ----------  Accessors:
+
+inline double  HepBoost::beta() const {   
+  return std::sqrt( 1.0 - 1.0 / (rep_.tt_ * rep_.tt_) );
+}
+
+inline double  HepBoost::gamma() const {
+  return rep_.tt_; 
+}
+
+inline Hep3Vector HepBoost::boostVector() const { 
+  return  (1.0/rep_.tt_) * Hep3Vector( rep_.xt_, rep_.yt_, rep_.zt_ );
+}
+
+inline Hep3Vector HepBoost::getDirection() const { 
+  double norm = 1.0/beta();
+  return  (norm*boostVector());
+}
+
+inline Hep3Vector HepBoost::direction() const { 
+  return  getDirection();
+}
+
+inline double HepBoost::xx() const { return rep_.xx_; }
+inline double HepBoost::xy() const { return rep_.xy_; }
+inline double HepBoost::xz() const { return rep_.xz_; }
+inline double HepBoost::xt() const { return rep_.xt_; }
+inline double HepBoost::yx() const { return rep_.xy_; }
+inline double HepBoost::yy() const { return rep_.yy_; }
+inline double HepBoost::yz() const { return rep_.yz_; }
+inline double HepBoost::yt() const { return rep_.yt_; }
+inline double HepBoost::zx() const { return rep_.xz_; }
+inline double HepBoost::zy() const { return rep_.yz_; }
+inline double HepBoost::zz() const { return rep_.zz_; }
+inline double HepBoost::zt() const { return rep_.zt_; }
+inline double HepBoost::tx() const { return rep_.xt_; }
+inline double HepBoost::ty() const { return rep_.yt_; }
+inline double HepBoost::tz() const { return rep_.zt_; }
+inline double HepBoost::tt() const { return rep_.tt_; }
+
+inline HepLorentzVector HepBoost::col1() const {
+  return HepLorentzVector ( xx(), yx(), zx(), tx() );
+}
+inline HepLorentzVector HepBoost::col2() const {
+  return HepLorentzVector ( xy(), yy(), zy(), ty() );
+}
+inline HepLorentzVector HepBoost::col3() const {
+  return HepLorentzVector ( xz(), yz(), zz(), tz() );
+}
+inline HepLorentzVector HepBoost::col4() const {
+  return HepLorentzVector ( xt(), yt(), zt(), tt() );
+}
+
+inline HepLorentzVector HepBoost::row1() const {
+  return HepLorentzVector ( col1() );
+}
+inline HepLorentzVector HepBoost::row2() const {
+  return HepLorentzVector ( col2() );
+}
+inline HepLorentzVector HepBoost::row3() const {
+  return HepLorentzVector ( col3() );
+}
+inline HepLorentzVector HepBoost::row4() const {
+  return HepLorentzVector ( col4() );
+}
+
+inline HepRep4x4 HepBoost::rep4x4() const {
+  return HepRep4x4( rep_ );
+}
+
+inline HepRep4x4Symmetric HepBoost::rep4x4Symmetric() const {
+  return rep_;
+}
+
+
+inline void HepBoost::setBoost(double bx, double by, double bz) {
+  set(bx, by, bz);
+}
+
+
+// ----------  Comparisons:
+
+int HepBoost::compare ( const HepBoost & b ) const {
+  const HepRep4x4Symmetric & s = b.rep4x4Symmetric();
+       if (rep_.tt_ < s.tt_) return -1; else if (rep_.tt_ > s.tt_) return 1;
+  else if (rep_.zt_ < s.zt_) return -1; else if (rep_.zt_ > s.zt_) return 1;
+  else if (rep_.zz_ < s.zz_) return -1; else if (rep_.zz_ > s.zz_) return 1;
+  else if (rep_.yt_ < s.yt_) return -1; else if (rep_.yt_ > s.yt_) return 1;
+  else if (rep_.yz_ < s.yz_) return -1; else if (rep_.yz_ > s.yz_) return 1;
+  else if (rep_.yy_ < s.yy_) return -1; else if (rep_.yy_ > s.yy_) return 1;
+  else if (rep_.xt_ < s.xt_) return -1; else if (rep_.xt_ > s.xt_) return 1;
+  else if (rep_.xz_ < s.xz_) return -1; else if (rep_.xz_ > s.xz_) return 1;
+  else if (rep_.xy_ < s.xy_) return -1; else if (rep_.xy_ > s.xy_) return 1;
+  else if (rep_.xx_ < s.xx_) return -1; else if (rep_.xx_ > s.xx_) return 1;
+  else return 0;
+}
+
+inline bool
+HepBoost::operator == (const HepBoost & b) const {
+  const HepRep4x4Symmetric & s = b.rep4x4Symmetric();
+  return ( 
+     rep_.xx_==s.xx_ && rep_.xy_==s.xy_ && rep_.xz_==s.xz_ && rep_.xt_==s.xt_ 
+ 		     && rep_.yy_==s.yy_ && rep_.yz_==s.yz_ && rep_.yt_==s.yt_ 
+					&& rep_.zz_==s.zz_ && rep_.zt_==s.zt_ 
+							   && rep_.tt_==s.tt_ 
+  );
+}
+
+inline bool
+HepBoost::operator != (const HepBoost & r) const {
+  return ( !(operator==(r)) );
+}
+inline bool HepBoost::operator <= ( const HepBoost & b ) const
+        { return compare(b)<= 0; }
+inline bool HepBoost::operator >= ( const HepBoost & b ) const
+        { return compare(b)>= 0; }
+inline bool HepBoost::operator <  ( const HepBoost & b ) const
+        { return compare(b)<  0; }
+inline bool HepBoost::operator >  ( const HepBoost & b ) const
+        { return compare(b)>  0; }
+
+inline bool HepBoost::isIdentity() const {
+  return (xx() == 1.0 && xy() == 0.0 && xz() == 0.0 && xt() == 0.0 
+          	      && yy() == 1.0 && yz() == 0.0 && yt() == 0.0 
+          		 	     && zz() == 1.0 && zt() == 0.0 
+          					    && tt() == 1.0);
+}
+
+inline double HepBoost::distance2( const HepBoost & b ) const {
+  double bgx = rep_.xt_ - b.rep_.xt_;
+  double bgy = rep_.yt_ - b.rep_.yt_;
+  double bgz = rep_.zt_ - b.rep_.zt_;
+  return bgx*bgx+bgy*bgy+bgz*bgz;
+}
+
+inline double HepBoost::distance2( const HepBoostX & bx ) const {
+  double bgx = rep_.xt_ - bx.beta()*bx.gamma();
+  double bgy = rep_.yt_;
+  double bgz = rep_.zt_;
+  return bgx*bgx+bgy*bgy+bgz*bgz;
+}
+
+inline double HepBoost::distance2( const HepBoostY & by ) const {
+  double bgy = rep_.xt_;
+  double bgx = rep_.yt_ - by.beta()*by.gamma();
+  double bgz = rep_.zt_;
+  return bgx*bgx+bgy*bgy+bgz*bgz;
+}
+
+inline double HepBoost::distance2( const HepBoostZ & bz ) const {
+  double bgz = rep_.xt_;
+  double bgy = rep_.yt_;
+  double bgx = rep_.zt_ - bz.beta()*bz.gamma();
+  return bgx*bgx+bgy*bgy+bgz*bgz;
+}
+
+inline double HepBoost::howNear ( const HepBoost & b ) const {
+  return std::sqrt(distance2(b));
+}
+
+inline bool HepBoost::isNear(const HepBoost & b, double epsilon) const{
+  return (distance2(b) <= epsilon*epsilon);
+}
+
+// ---------- Application:
+
+// - Protected method:
+inline HepLorentzVector
+HepBoost::vectorMultiplication(const HepLorentzVector & p) const {
+  register double x = p.x();
+  register double y = p.y();
+  register double z = p.z();
+  register double t = p.t();
+  return HepLorentzVector( rep_.xx_*x + rep_.xy_*y + rep_.xz_*z + rep_.xt_*t,
+			   rep_.xy_*x + rep_.yy_*y + rep_.yz_*z + rep_.yt_*t,
+			   rep_.xz_*x + rep_.yz_*y + rep_.zz_*z + rep_.zt_*t,
+			   rep_.xt_*x + rep_.yt_*y + rep_.zt_*z + rep_.tt_*t);
+}
+
+inline HepLorentzVector
+HepBoost::operator () (const HepLorentzVector & p) const {
+  return vectorMultiplication(p);
+}
+
+inline HepLorentzVector
+HepBoost::operator * (const HepLorentzVector & p) const {
+  return vectorMultiplication(p);
+}
+
+
+// ---------- Operations in the group of 4-Rotations
+
+inline HepBoost HepBoost::inverse() const {
+  return HepBoost( xx(),  yx(),  zx(), -tx(),
+                   	  yy(),  zy(), -ty(),
+                   		 zz(), -tz(),
+                  			tt());
+}
+
+inline HepBoost inverseOf ( const HepBoost & lt ) {
+  return HepBoost( lt.xx(),  lt.yx(),  lt.zx(), -lt.tx(),
+                             lt.yy(),  lt.zy(), -lt.ty(),
+                             	       lt.zz(), -lt.tz(),
+                            			 lt.tt());
+}
+
+inline HepBoost & HepBoost::invert() {
+  rep_.xt_ = -rep_.xt_;
+  rep_.yt_ = -rep_.yt_;
+  rep_.zt_ = -rep_.zt_;
+  return *this;
+}
+
+// ---------- Tolerance:
+
+inline double HepBoost::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepBoost::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/BoostX.h
===================================================================
--- trunk/CLHEP/Vector/BoostX.h	(revision 4)
+++ trunk/CLHEP/Vector/BoostX.h	(revision 4)
@@ -0,0 +1,227 @@
+// -*- C++ -*-
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepBoostX class for performing specialized
+// Lorentz transformations which are pure boosts in the X direction, on 
+// objects of the HepLorentzVector class.
+//
+// HepLorentzRotation is a concrete implementation of Hep4RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// LorentzVector.h LorentzRotation.h 
+// Boost.h 
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_BOOSTX_H
+#define HEP_BOOSTX_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP  {
+
+// Declarations of classes and global methods
+class HepBoostX;
+inline HepBoostX inverseOf ( const HepBoostX & b );
+class HepBoost;
+class HepRotation;
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepBoostX {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepBoostX();
+  // Default constructor. Gives a boost of 0.  
+
+  inline HepBoostX(const HepBoostX & b);
+  // Copy constructor.
+
+  inline HepBoostX & operator = (const HepBoostX & m);
+  // Assignment.
+
+         HepBoostX & set (double beta);
+  inline HepBoostX       (double beta);
+  // Constructor from beta 
+
+  // ----------  Accessors:
+
+  inline double  beta()  const;
+  inline double  gamma() const;
+  inline Hep3Vector boostVector() const;
+  inline Hep3Vector getDirection() const;
+
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double xt() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double yt() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  inline double tt() const;
+  // Elements of the matrix.
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  inline HepLorentzVector col4() const;
+  // orthosymplectic column vectors
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  inline HepLorentzVector row4() const;
+  // orthosymplectic row vectors
+
+  HepRep4x4 rep4x4() const;
+  //   4x4 representation:
+
+  HepRep4x4Symmetric rep4x4Symmetric() const;
+  //   Symmetric 4x4 representation.
+
+  // ----------  Decomposition:
+
+  void decompose (HepRotation  & rotation, HepBoost   & boost) const;
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  // Find R and B such that L = R*B -- trivial, since R is identity
+
+  void decompose ( HepBoost  & boost, HepRotation  & rotation) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  // Find R and B such that L = B*R -- trivial, since R is identity
+
+  // ----------  Comparisons:
+
+  inline int compare( const HepBoostX & b  ) const;
+  // Dictionary-order comparison, in order of beta. 
+  // Used in operator<, >, <=, >=
+
+  inline bool operator == (const HepBoostX & b) const;
+  inline bool operator != (const HepBoostX & b) const;
+  inline bool operator <= (const HepBoostX & b) const;
+  inline bool operator >= (const HepBoostX & b) const;
+  inline bool operator <  (const HepBoostX & b) const;
+  inline bool operator >  (const HepBoostX & b) const;
+  // Comparisons.
+
+  inline bool isIdentity() const;
+  // Returns true if a null boost.
+
+  inline double distance2( const HepBoostX & b ) const;
+         double distance2( const HepBoost & b ) const;
+  // Defined as the distance2 between the vectors (gamma*betaVector)
+
+  double distance2( const HepRotation & r  ) const;
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // Decompose lt = B*R; add norm2 to distance2 to between boosts.
+
+  inline double howNear(   const HepBoostX & b ) const;
+  inline double howNear(   const HepBoost  & b ) const;
+  inline double howNear(   const HepRotation & r ) const;
+  inline double howNear(   const HepLorentzRotation & lt ) const;
+
+  inline bool isNear(   const HepBoostX & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  inline bool isNear(   const HepBoost & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepRotation & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  inline double norm2() const;
+  // distance2 (IDENTITY), which is beta^2 * gamma^2
+
+  void rectify();
+  // sets according to the stored beta
+
+  // ---------- Application:
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Transform a Lorentz Vector.             
+
+  inline HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  // ---------- Operations in the group of 4-Rotations
+
+  HepBoostX   operator * (const HepBoostX & b) const;
+  HepLorentzRotation operator * (const HepBoost & b) const;
+  HepLorentzRotation operator * (const HepRotation & r) const;
+  HepLorentzRotation operator * (const HepLorentzRotation & lt) const;
+  // Product of two Lorentz Rotations (this) * lt - matrix multiplication
+  // Notice that the product of two pure boosts in different directions
+  // is no longer a pure boost.
+
+  inline HepBoostX inverse() const;
+  // Return the inverse.
+
+  inline friend HepBoostX inverseOf ( const HepBoostX & b );
+  // global methods to invert.
+
+  inline HepBoostX & invert();
+  // Inverts the Boost matrix.
+
+  // ---------- I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output form is BOOSTX (beta=..., gamma=...);  
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  inline HepLorentzVector vectorMultiplication
+                                        ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  HepLorentzRotation matrixMultiplication (const HepRep4x4 & m) const;
+  HepLorentzRotation matrixMultiplication (const HepRep4x4Symmetric & m) const;
+                   
+  inline HepBoostX (double beta, double gamma);
+
+  double  beta_;
+  double  gamma_;
+
+};  // HepBoostX
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepBoostX& b ) {return b.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/BoostX.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_BOOSTX_H */
Index: trunk/CLHEP/Vector/BoostX.icc
===================================================================
--- trunk/CLHEP/Vector/BoostX.icc	(revision 4)
+++ trunk/CLHEP/Vector/BoostX.icc	(revision 4)
@@ -0,0 +1,200 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepBoostX class
+//
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+inline HepBoostX::HepBoostX() : beta_(0.0), gamma_(1.0) {}
+
+inline HepBoostX::HepBoostX(const HepBoostX & b) : 
+	beta_ (b.beta_), 
+	gamma_(b.gamma_) {}
+
+inline HepBoostX & HepBoostX::operator = (const HepBoostX & b) { 
+  beta_  = b.beta_; 
+  gamma_ = b.gamma_;
+  return *this;
+}
+
+inline HepBoostX::HepBoostX(double beta) { set(beta); }
+
+// - Protected method:
+inline HepBoostX::HepBoostX( double beta, double gamma ) :
+                                        beta_(beta), gamma_(gamma) {}
+
+// ----------  Accessors:
+
+inline double  HepBoostX::beta() const {   
+  return beta_;
+}
+
+inline double  HepBoostX::gamma() const {
+  return gamma_;
+}
+
+inline Hep3Vector HepBoostX::boostVector() const { 
+  return  Hep3Vector( beta_, 0, 0 );
+}
+
+inline Hep3Vector HepBoostX::getDirection() const { 
+  return  Hep3Vector(1.0, 0.0, 0.0);
+}
+
+inline double HepBoostX::xx() const { return gamma();}
+inline double HepBoostX::xy() const { return 0.0;}
+inline double HepBoostX::xz() const { return 0.0;}
+inline double HepBoostX::xt() const { return beta()*gamma();}
+inline double HepBoostX::yx() const { return 0.0;}
+inline double HepBoostX::yy() const { return 1.0;}
+inline double HepBoostX::yz() const { return 0.0;}
+inline double HepBoostX::yt() const { return 0.0;}
+inline double HepBoostX::zx() const { return 0.0;}
+inline double HepBoostX::zy() const { return 0.0;}
+inline double HepBoostX::zz() const { return 1.0;}
+inline double HepBoostX::zt() const { return 0.0;}
+inline double HepBoostX::tx() const { return beta()*gamma();}
+inline double HepBoostX::ty() const { return 0.0;}
+inline double HepBoostX::tz() const { return 0.0;}
+inline double HepBoostX::tt() const { return gamma();}
+
+inline HepLorentzVector HepBoostX::col1() const {
+  return HepLorentzVector ( gamma(), 0, 0, beta()*gamma() );
+}
+inline HepLorentzVector HepBoostX::col2() const {
+  return HepLorentzVector ( 0, 1, 0, 0 );
+}
+inline HepLorentzVector HepBoostX::col3() const {
+  return HepLorentzVector ( 0, 0, 1, 0 );
+}
+inline HepLorentzVector HepBoostX::col4() const {
+  return HepLorentzVector ( beta()*gamma(), 0, 0, gamma() );
+}
+
+inline HepLorentzVector HepBoostX::row1() const {
+  return HepLorentzVector ( col1() );
+}
+inline HepLorentzVector HepBoostX::row2() const {
+  return HepLorentzVector ( col2() );
+}
+inline HepLorentzVector HepBoostX::row3() const {
+  return HepLorentzVector ( col3() );
+}
+inline HepLorentzVector HepBoostX::row4() const {
+  return HepLorentzVector ( col4() );
+}
+
+// ----------  Comparisons:
+
+inline int HepBoostX::compare( const HepBoostX & b ) const {
+  if (beta() < b.beta()) {
+    return -1;
+  } else if (beta() > b.beta()) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+inline bool HepBoostX::operator == ( const HepBoostX & b ) const {
+  return beta_ == b.beta_;
+}
+inline bool HepBoostX::operator != ( const HepBoostX & b ) const {
+  return beta_ != b.beta_;
+}
+inline bool HepBoostX::operator <= ( const HepBoostX & b ) const {
+  return beta_ <= b.beta_;
+}
+inline bool HepBoostX::operator >= ( const HepBoostX & b ) const {
+  return beta_ >= b.beta_;
+}
+inline bool HepBoostX::operator <  ( const HepBoostX & b ) const {
+  return beta_ <  b.beta_;
+}
+inline bool HepBoostX::operator >  ( const HepBoostX & b ) const {
+  return beta_ >  b.beta_;
+}
+
+inline bool HepBoostX::isIdentity() const {
+  return ( beta() == 0 );
+}
+
+inline double HepBoostX::distance2( const HepBoostX & b ) const {
+  double d = beta()*gamma() - b.beta()*b.gamma();
+  return d*d;
+}
+
+inline double HepBoostX::howNear(const HepBoostX & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostX::howNear(const HepBoost  & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostX::howNear(const HepRotation & r) const {
+  return std::sqrt(distance2(r)); }
+inline double HepBoostX::howNear(const HepLorentzRotation & lt) const {
+  return std::sqrt(distance2(lt)); }
+
+inline bool HepBoostX::isNear(const HepBoostX & b, 
+					double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+inline bool HepBoostX::isNear(const HepBoost & b, 
+					double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+
+// ----------  Properties:
+
+inline double HepBoostX::norm2() const {
+  register double bg = beta_*gamma_;
+  return bg*bg;
+}
+
+// ---------- Application:
+
+inline HepLorentzVector
+HepBoostX::operator * (const HepLorentzVector & p) const {
+  double bg = beta_*gamma_;
+  return HepLorentzVector(gamma_*p.x() + bg*p.t(),
+				 p.y(),
+				 p.z(),
+			  gamma_*p.t() + bg*p.x());
+}
+
+inline HepLorentzVector 
+HepBoostX::operator() (const HepLorentzVector & w) const {
+  return operator*(w);
+}
+
+// ---------- Operations in the group of 4-Rotations
+
+inline HepBoostX HepBoostX::inverse() const {
+  return HepBoostX( -beta(), gamma() );
+}
+
+inline HepBoostX inverseOf ( const HepBoostX & b ) {
+  return HepBoostX( -b.beta(), b.gamma());
+}
+
+inline HepBoostX & HepBoostX::invert() {
+  beta_ = -beta_;
+  return *this;
+}
+
+// ---------- Tolerance:
+
+inline double HepBoostX::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepBoostX::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/BoostY.h
===================================================================
--- trunk/CLHEP/Vector/BoostY.h	(revision 4)
+++ trunk/CLHEP/Vector/BoostY.h	(revision 4)
@@ -0,0 +1,228 @@
+// -*- C++ -*-
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepBoostY class for performing specialized
+// Lorentz transformations which are pure boosts in the Y direction, on 
+// objects of the HepLorentzVector class.
+//
+// HepLorentzRotation is a concrete implementation of Hep4RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// LorentzVector.h LorentzRotation.h 
+// Boost.h 
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_BOOSTY_H
+#define HEP_BOOSTY_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP  {
+
+// Declarations of classes and global methods
+class HepBoostY;               
+inline HepBoostY inverseOf ( const HepBoostY & b ); 
+class HepBoost;
+class HepRotation;
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepBoostY {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepBoostY();
+  // Default constructor. Gives a boost of 0.  
+
+  inline HepBoostY(const HepBoostY & b);
+  // Copy constructor.
+
+  inline HepBoostY & operator = (const HepBoostY & m);
+  // Assignment.
+
+         HepBoostY & set (double beta);
+  inline HepBoostY       (double beta);
+  // Constructor from beta 
+
+  // ----------  Accessors:
+
+  inline double  beta()  const;
+  inline double  gamma() const;
+  inline Hep3Vector boostVector() const;
+  inline Hep3Vector getDirection() const;
+
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double xt() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double yt() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  inline double tt() const;
+  // Elements of the matrix.
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  inline HepLorentzVector col4() const;
+  // orthosymplectic column vectors
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  inline HepLorentzVector row4() const;
+  // orthosymplectic row vectors
+
+  HepRep4x4 rep4x4() const;
+  //   4x4 representation:
+
+  HepRep4x4Symmetric rep4x4Symmetric() const;
+  //   Symmetric 4x4 representation.
+
+
+  // ----------  Decomposition:
+
+  void decompose (HepRotation  & rotation, HepBoost   & boost) const;
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  // Find R and B such that L = R*B -- trivial, since R is identity
+
+  void decompose (HepBoost  & boost, HepRotation   & rotation) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  // Find R and B such that L = B*R -- trivial, since R is identity
+
+  // ----------  Comparisons:
+
+  inline int compare( const HepBoostY & b  ) const;
+  // Dictionary-order comparison, in order of beta. 
+  // Used in operator<, >, <=, >=
+
+  inline bool operator == (const HepBoostY & b) const;
+  inline bool operator != (const HepBoostY & b) const;
+  inline bool operator <= (const HepBoostY & b) const;
+  inline bool operator >= (const HepBoostY & b) const;
+  inline bool operator <  (const HepBoostY & b) const;
+  inline bool operator >  (const HepBoostY & b) const;
+  // Comparisons.
+
+  inline bool isIdentity() const;
+  // Returns true if a null boost.
+
+  inline  double distance2( const HepBoostY & b ) const;
+  	  double distance2( const HepBoost & b ) const;
+  // Defined as the distance2 between the vectors (gamma*betaVector)
+
+  double distance2( const HepRotation & r  ) const;
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // Decompose lt = B*R; add norm2 to distance2 to between boosts.
+
+  inline double howNear(   const HepBoostY & b ) const;
+  inline double howNear(   const HepBoost  & b ) const;
+  inline double howNear(   const HepRotation & r ) const;
+  inline double howNear(   const HepLorentzRotation & lt ) const;
+
+  inline bool isNear(   const HepBoostY & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  inline bool isNear(   const HepBoost & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepRotation & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  inline double norm2() const;
+  // distance2 (IDENTITY), which is beta^2 * gamma^2
+
+  void rectify();
+  // sets according to the stored beta
+
+  // ---------- Application:
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Transform a Lorentz Vector.             
+
+  inline HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  // ---------- Operations in the group of 4-Rotations
+
+  HepBoostY   operator * (const HepBoostY & b) const;
+  HepLorentzRotation operator * (const HepBoost & b) const;
+  HepLorentzRotation operator * (const HepRotation & r) const;
+  HepLorentzRotation operator * (const HepLorentzRotation & lt) const;
+  // Product of two Lorentz Rotations (this) * lt - matrix multiplication
+  // Notice that the product of two pure boosts in different directions
+  // is no longer a pure boost.
+
+  inline HepBoostY inverse() const;
+  // Return the inverse.
+
+  inline friend HepBoostY inverseOf ( const HepBoostY & b );
+  // global methods to invert.
+
+  inline HepBoostY & invert();
+  // Inverts the Boost matrix.
+
+  // ---------- I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output form is BOOSTY (beta=..., gamma=...);  
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  inline HepLorentzVector vectorMultiplication
+                                        ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  HepLorentzRotation matrixMultiplication (const HepRep4x4 & m) const;
+  HepLorentzRotation matrixMultiplication (const HepRep4x4Symmetric & m) const;
+                   
+  inline HepBoostY (double beta, double gamma);
+
+  double  beta_;
+  double  gamma_;
+
+};  // HepBoostY
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepBoostY& b ) {return b.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/BoostY.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_BOOSTY_H */
Index: trunk/CLHEP/Vector/BoostY.icc
===================================================================
--- trunk/CLHEP/Vector/BoostY.icc	(revision 4)
+++ trunk/CLHEP/Vector/BoostY.icc	(revision 4)
@@ -0,0 +1,200 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepBoostY class
+//
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+inline HepBoostY::HepBoostY() : beta_(0.0), gamma_(1.0) {}
+
+inline HepBoostY::HepBoostY(const HepBoostY & b) : 
+	beta_ (b.beta_), 
+	gamma_(b.gamma_) {}
+
+inline HepBoostY & HepBoostY::operator = (const HepBoostY & b) { 
+  beta_  = b.beta_; 
+  gamma_ = b.gamma_;
+  return *this;
+}
+
+inline HepBoostY::HepBoostY(double beta) { set(beta); }
+
+// - Protected method:
+inline HepBoostY::HepBoostY( double beta, double gamma ) :
+                                        beta_(beta), gamma_(gamma) {}
+
+// ----------  Accessors:
+
+inline double  HepBoostY::beta() const {   
+  return beta_;
+}
+
+inline double  HepBoostY::gamma() const {
+  return gamma_;
+}
+
+inline Hep3Vector HepBoostY::boostVector() const { 
+  return  Hep3Vector( 0, beta_, 0 );
+}
+
+inline Hep3Vector HepBoostY::getDirection() const { 
+  return  Hep3Vector( 0.0, 1.0, 0.0 );
+}
+
+inline double HepBoostY::xx() const { return 1.0;}
+inline double HepBoostY::xy() const { return 0.0;}
+inline double HepBoostY::xz() const { return 0.0;}
+inline double HepBoostY::xt() const { return 0.0;}
+inline double HepBoostY::yx() const { return 0.0;}
+inline double HepBoostY::yy() const { return gamma();}
+inline double HepBoostY::yz() const { return 0.0;}
+inline double HepBoostY::yt() const { return beta()*gamma();}
+inline double HepBoostY::zx() const { return 0.0;}
+inline double HepBoostY::zy() const { return 0.0;}
+inline double HepBoostY::zz() const { return 1.0;}
+inline double HepBoostY::zt() const { return 0.0;}
+inline double HepBoostY::tx() const { return 0.0;}
+inline double HepBoostY::ty() const { return beta()*gamma();}
+inline double HepBoostY::tz() const { return 0.0;}
+inline double HepBoostY::tt() const { return gamma();}
+
+inline HepLorentzVector HepBoostY::col1() const {
+  return HepLorentzVector ( 1, 0, 0, 0 );
+}
+inline HepLorentzVector HepBoostY::col2() const {
+  return HepLorentzVector ( 0, gamma(), 0, beta()*gamma() );
+}
+inline HepLorentzVector HepBoostY::col3() const {
+  return HepLorentzVector ( 0, 0, 1, 0 );
+}
+inline HepLorentzVector HepBoostY::col4() const {
+  return HepLorentzVector ( 0, beta()*gamma(), 0, gamma() );
+}
+
+inline HepLorentzVector HepBoostY::row1() const {
+  return HepLorentzVector ( col1() );
+}
+inline HepLorentzVector HepBoostY::row2() const {
+  return HepLorentzVector ( col2() );
+}
+inline HepLorentzVector HepBoostY::row3() const {
+  return HepLorentzVector ( col3() );
+}
+inline HepLorentzVector HepBoostY::row4() const {
+  return HepLorentzVector ( col4() );
+}
+
+// ----------  Comparisons:
+
+inline int HepBoostY::compare( const HepBoostY & b ) const {
+  if (beta() < b.beta()) {
+    return -1;
+  } else if (beta() > b.beta()) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+inline bool HepBoostY::operator == ( const HepBoostY & b ) const {
+  return beta_ == b.beta_;
+}
+inline bool HepBoostY::operator != ( const HepBoostY & b ) const {
+  return beta_ != b.beta_;
+}
+inline bool HepBoostY::operator <= ( const HepBoostY & b ) const {
+  return beta_ <= b.beta_;
+}
+inline bool HepBoostY::operator >= ( const HepBoostY & b ) const {
+  return beta_ >= b.beta_;
+}
+inline bool HepBoostY::operator <  ( const HepBoostY & b ) const {
+  return beta_ <  b.beta_;
+}
+inline bool HepBoostY::operator >  ( const HepBoostY & b ) const {
+  return beta_ >  b.beta_;
+}
+
+
+inline bool HepBoostY::isIdentity() const {
+  return ( beta() == 0 );
+}
+
+inline double HepBoostY::distance2( const HepBoostY & b ) const {
+  double d = beta()*gamma() - b.beta()*b.gamma();
+  return d*d;
+}
+
+inline double HepBoostY::howNear(const HepBoostY & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostY::howNear(const HepBoost  & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostY::howNear(const HepRotation & r) const {
+  return std::sqrt(distance2(r)); }
+inline double HepBoostY::howNear(const HepLorentzRotation & lt) const {
+  return std::sqrt(distance2(lt)); }
+
+inline bool HepBoostY::isNear(const HepBoostY & b,
+                                        double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+inline bool HepBoostY::isNear(const HepBoost & b,
+                                        double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+
+// ----------  Properties:
+
+double HepBoostY::norm2() const {
+  register double bg = beta_*gamma_;
+  return bg*bg;
+}
+
+// ---------- Application:
+
+inline HepLorentzVector
+HepBoostY::operator * (const HepLorentzVector & p) const {
+  double bg = beta_*gamma_;
+  return HepLorentzVector(	 p.x(),
+			  gamma_*p.y() + bg*p.t(),
+				 p.z(),
+			  gamma_*p.t() + bg*p.y());
+}
+
+HepLorentzVector HepBoostY::operator() (const HepLorentzVector & w) const {
+  return operator*(w);
+}
+
+// ---------- Operations in the group of 4-Rotations
+
+inline HepBoostY HepBoostY::inverse() const {
+  return HepBoostY( -beta(), gamma() );
+}
+
+inline HepBoostY inverseOf ( const HepBoostY & b ) {
+  return HepBoostY( -b.beta(), b.gamma());
+}
+
+inline HepBoostY & HepBoostY::invert() {
+  beta_ = -beta_;
+  return *this;
+}
+
+// ---------- Tolerance:
+
+inline double HepBoostY::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepBoostY::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/BoostZ.h
===================================================================
--- trunk/CLHEP/Vector/BoostZ.h	(revision 4)
+++ trunk/CLHEP/Vector/BoostZ.h	(revision 4)
@@ -0,0 +1,227 @@
+// -*- C++ -*-
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepBoostZ class for performing specialized
+// Lorentz transformations which are pure boosts in the Z direction, on 
+// objects of the HepLorentzVector class.
+//
+// HepLorentzRotation is a concrete implementation of Hep4RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// LorentzVector.h LorentzRotation.h 
+// Boost.h 
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_BOOSTZ_H
+#define HEP_BOOSTZ_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP  {
+
+// Declarations of classes and global methods
+class HepBoostZ;               
+inline HepBoostZ inverseOf ( const HepBoostZ & b ); 
+class HepBoost;
+class HepRotation;
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepBoostZ {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepBoostZ();
+  // Default constructor. Gives a boost of 0.  
+
+  inline HepBoostZ(const HepBoostZ & b);
+  // Copy constructor.
+
+  inline HepBoostZ & operator = (const HepBoostZ & m);
+  // Assignment.
+
+         HepBoostZ & set (double beta);
+  inline HepBoostZ       (double beta);
+  // Constructor from beta 
+
+  // ----------  Accessors:
+
+  inline double  beta()  const;
+  inline double  gamma() const;
+  inline Hep3Vector boostVector() const;
+  inline Hep3Vector getDirection() const;
+
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double xt() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double yt() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  inline double tt() const;
+  // Elements of the matrix.
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  inline HepLorentzVector col4() const;
+  // orthosymplectic column vectors
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  inline HepLorentzVector row4() const;
+  // orthosymplectic row vectors
+
+  HepRep4x4 rep4x4() const;
+  //   4x4 representation:
+
+  HepRep4x4Symmetric rep4x4Symmetric() const;
+  //   Symmetric 4x4 representation.
+
+  // ----------  Decomposition:
+
+  void decompose (HepRotation  & rotation, HepBoost   & boost) const;
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  // Find R and B such that L = R*B -- trivial, since R is identity
+
+  void decompose (HepBoost   & boost, HepRotation  & rotation) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  // Find R and B such that L = B*R -- trivial, since R is identity
+
+  // ----------  Comparisons:
+
+  inline int compare( const HepBoostZ & b  ) const;
+  // Dictionary-order comparison, in order of beta. 
+  // Used in operator<, >, <=, >=
+
+  inline bool operator == (const HepBoostZ & b) const;
+  inline bool operator != (const HepBoostZ & b) const;
+  inline bool operator <= (const HepBoostZ & b) const;
+  inline bool operator >= (const HepBoostZ & b) const;
+  inline bool operator <  (const HepBoostZ & b) const;
+  inline bool operator >  (const HepBoostZ & b) const;
+  // Comparisons.
+
+  inline bool isIdentity() const;
+  // Returns true if a null boost.
+
+  inline  double distance2( const HepBoostZ & b ) const;
+  	  double distance2( const HepBoost & b ) const;
+  // Defined as the distance2 between the vectors (gamma*betaVector)
+
+  double distance2( const HepRotation & r  ) const;
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // Decompose lt = B*R; add norm2 to distance2 to between boosts.
+
+  inline double howNear(   const HepBoostZ & b ) const;
+  inline double howNear(   const HepBoost  & b ) const;
+  inline double howNear(   const HepRotation & r ) const;
+  inline double howNear(   const HepLorentzRotation & lt ) const;
+
+  inline bool isNear(   const HepBoostZ & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  inline bool isNear(   const HepBoost & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepRotation & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(   const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  inline double norm2() const;
+  // distance2 (IDENTITY), which is beta^2 * gamma^2
+
+  void rectify();
+  // sets according to the stored beta
+
+  // ---------- Application:
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Transform a Lorentz Vector.             
+
+  inline HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  // ---------- Operations in the group of 4-Rotations
+
+  HepBoostZ   operator * (const HepBoostZ & b) const;
+  HepLorentzRotation operator * (const HepBoost & b) const;
+  HepLorentzRotation operator * (const HepRotation & r) const;
+  HepLorentzRotation operator * (const HepLorentzRotation & lt) const;
+  // Product of two Lorentz Rotations (this) * lt - matrix multiplication
+  // Notice that the product of two pure boosts in different directions
+  // is no longer a pure boost.
+
+  inline HepBoostZ inverse() const;
+  // Return the inverse.
+
+  inline friend HepBoostZ inverseOf ( const HepBoostZ & b );
+  // global methods to invert.
+
+  inline HepBoostZ & invert();
+  // Inverts the Boost matrix.
+
+  // ---------- I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output form is BOOSTZ (beta=..., gamma=...);  
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  inline HepLorentzVector vectorMultiplication
+                                        ( const HepLorentzVector & w ) const;
+  // Multiplication with a Lorentz Vector.
+
+  HepLorentzRotation matrixMultiplication (const HepRep4x4 & m) const;
+  HepLorentzRotation matrixMultiplication (const HepRep4x4Symmetric & m) const;
+                   
+  inline HepBoostZ (double beta, double gamma);
+
+  double  beta_;
+  double  gamma_;
+
+};  // HepBoostZ
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepBoostZ& b ) {return b.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/BoostZ.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_BOOSTZ_H */
Index: trunk/CLHEP/Vector/BoostZ.icc
===================================================================
--- trunk/CLHEP/Vector/BoostZ.icc	(revision 4)
+++ trunk/CLHEP/Vector/BoostZ.icc	(revision 4)
@@ -0,0 +1,199 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepBoostZ class
+//
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+inline HepBoostZ::HepBoostZ() : beta_(0.0), gamma_(1.0) {}
+
+inline HepBoostZ::HepBoostZ(const HepBoostZ & b) : 
+	beta_ (b.beta_), 
+	gamma_(b.gamma_) {}
+
+inline HepBoostZ & HepBoostZ::operator = (const HepBoostZ & b) { 
+  beta_  = b.beta_; 
+  gamma_ = b.gamma_;
+  return *this;
+}
+
+inline HepBoostZ::HepBoostZ(double beta) { set(beta); }
+
+// - Protected method:
+inline HepBoostZ::HepBoostZ( double beta, double gamma ) : 
+					beta_(beta), gamma_(gamma) {}
+
+// ----------  Accessors:
+
+inline double  HepBoostZ::beta() const {   
+  return beta_;
+}
+
+inline double  HepBoostZ::gamma() const {
+  return gamma_;
+}
+
+inline Hep3Vector HepBoostZ::boostVector() const { 
+  return  Hep3Vector( 0, 0, beta_ );
+}
+
+inline Hep3Vector HepBoostZ::getDirection() const { 
+  return  Hep3Vector( 0.0, 0.0, 1.0 );
+}
+
+inline double HepBoostZ::xx() const { return 1.0;}
+inline double HepBoostZ::xy() const { return 0.0;}
+inline double HepBoostZ::xz() const { return 0.0;}
+inline double HepBoostZ::xt() const { return 0.0;}
+inline double HepBoostZ::yx() const { return 0.0;}
+inline double HepBoostZ::yy() const { return 1.0;}
+inline double HepBoostZ::yz() const { return 0.0;}
+inline double HepBoostZ::yt() const { return 0.0;}
+inline double HepBoostZ::zx() const { return 0.0;}
+inline double HepBoostZ::zy() const { return 0.0;}
+inline double HepBoostZ::zz() const { return gamma();}
+inline double HepBoostZ::zt() const { return beta()*gamma();}
+inline double HepBoostZ::tx() const { return 0.0;}
+inline double HepBoostZ::ty() const { return 0.0;}
+inline double HepBoostZ::tz() const { return beta()*gamma();}
+inline double HepBoostZ::tt() const { return gamma();}
+
+inline HepLorentzVector HepBoostZ::col1() const {
+  return HepLorentzVector ( 1, 0, 0, 0 );
+}
+inline HepLorentzVector HepBoostZ::col2() const {
+  return HepLorentzVector ( 0, 1, 0, 0 );
+}
+inline HepLorentzVector HepBoostZ::col3() const {
+  return HepLorentzVector ( 0, 0, gamma(), beta()*gamma() );
+}
+inline HepLorentzVector HepBoostZ::col4() const {
+  return HepLorentzVector ( 0, 0, beta()*gamma(), gamma() );
+}
+
+inline HepLorentzVector HepBoostZ::row1() const {
+  return HepLorentzVector ( col1() );
+}
+inline HepLorentzVector HepBoostZ::row2() const {
+  return HepLorentzVector ( col2() );
+}
+inline HepLorentzVector HepBoostZ::row3() const {
+  return HepLorentzVector ( col3() );
+}
+inline HepLorentzVector HepBoostZ::row4() const {
+  return HepLorentzVector ( col4() );
+}
+
+// ----------  Comparisons:
+
+inline int HepBoostZ::compare( const HepBoostZ & b ) const {
+  if (beta() < b.beta()) {
+    return -1;
+  } else if (beta() > b.beta()) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+inline bool HepBoostZ::operator == ( const HepBoostZ & b ) const {
+  return beta_ == b.beta_;
+}
+inline bool HepBoostZ::operator != ( const HepBoostZ & b ) const {
+  return beta_ != b.beta_;
+}
+inline bool HepBoostZ::operator <= ( const HepBoostZ & b ) const {
+  return beta_ <= b.beta_;
+}
+inline bool HepBoostZ::operator >= ( const HepBoostZ & b ) const {
+  return beta_ >= b.beta_;
+}
+inline bool HepBoostZ::operator <  ( const HepBoostZ & b ) const {
+  return beta_ <  b.beta_;
+}
+inline bool HepBoostZ::operator >  ( const HepBoostZ & b ) const {
+  return beta_ >  b.beta_;
+}
+
+inline bool HepBoostZ::isIdentity() const {
+  return ( beta() == 0 );
+}
+
+inline double HepBoostZ::distance2( const HepBoostZ & b ) const {
+  double d = beta()*gamma() - b.beta()*b.gamma();
+  return d*d;
+}
+
+inline double HepBoostZ::howNear(const HepBoostZ & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostZ::howNear(const HepBoost  & b) const {
+  return std::sqrt(distance2(b)); }
+inline double HepBoostZ::howNear(const HepRotation & r) const {
+  return std::sqrt(distance2(r)); }
+inline double HepBoostZ::howNear(const HepLorentzRotation & lt) const {
+  return std::sqrt(distance2(lt)); }
+
+inline bool HepBoostZ::isNear(const HepBoostZ & b,
+                                        double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+inline bool HepBoostZ::isNear(const HepBoost & b,
+                                        double epsilon) const {
+  return (distance2(b) <= epsilon*epsilon);
+}
+
+// ----------  Properties:
+
+double HepBoostZ::norm2() const {
+  register double bg = beta_*gamma_;
+  return bg*bg;
+}
+
+// ---------- Application:
+
+inline HepLorentzVector
+HepBoostZ::operator * (const HepLorentzVector & p) const {
+  double bg = beta_*gamma_;
+  return HepLorentzVector(	 p.x(),
+				 p.y(),
+			  gamma_*p.z() + bg*p.t(),	 
+			  gamma_*p.t() + bg*p.z());
+}
+
+HepLorentzVector HepBoostZ::operator() (const HepLorentzVector & w) const {
+  return operator*(w);
+}
+
+// ---------- Operations in the group of 4-Rotations
+
+inline HepBoostZ HepBoostZ::inverse() const {
+  return HepBoostZ( -beta(), gamma() );
+}
+
+inline HepBoostZ & HepBoostZ::invert() {
+  beta_ = -beta_;
+  return *this;
+}
+
+inline HepBoostZ inverseOf ( const HepBoostZ & b ) {
+  return HepBoostZ( -b.beta(), b.gamma());
+}
+
+// ---------- Tolerance:
+
+inline double HepBoostZ::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepBoostZ::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/EulerAngles.h
===================================================================
--- trunk/CLHEP/Vector/EulerAngles.h	(revision 4)
+++ trunk/CLHEP/Vector/EulerAngles.h	(revision 4)
@@ -0,0 +1,120 @@
+#ifndef HEP_EULERANGLES_H
+#define HEP_EULERANGLES_H
+
+// ----------------------------------------------------------------------
+//
+//  EulerAngles.h 	EulerAngles class --
+//  			Support class for PhysicsVectors classes
+//
+// History:
+//   09-Jan-1998  WEB  FixedTypes is now found in ZMutility
+//   12-Jan-1998  WEB  PI is now found in ZMutility
+//   15-Jun-1998  WEB  Added namespace support
+//   02-May-2000  WEB  No global using
+//   26-Jul-2000  MF   CLHEP version
+//
+// ----------------------------------------------------------------------
+
+#include <iostream>
+#include "CLHEP/Vector/defs.h" 
+
+namespace CLHEP {
+
+// Declarations of classes and global methods
+class HepEulerAngles;
+std::ostream & operator<<(std::ostream & os, const HepEulerAngles & aa);
+std::istream & operator>>(std::istream & is,       HepEulerAngles & aa);
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepEulerAngles {
+
+protected:
+  typedef HepEulerAngles EA;       // just an abbreviation
+  static double tolerance;      // to determine relative nearness
+
+public:
+
+  // ----------  Constructors:
+  inline HepEulerAngles();
+  inline HepEulerAngles( double phi, double theta, double psi );
+
+  // ----------  Destructor, copy constructor, assignment:
+  // use C++ defaults
+
+  // ----------  Accessors:
+
+public:
+  inline  double  getPhi() const;
+  inline  double  phi()    const;
+  inline  EA &       setPhi( double phi );
+
+  inline  double  getTheta() const;
+  inline  double  theta()    const;
+  inline  EA &       setTheta( double theta );
+
+  inline  double  getPsi() const;
+  inline  double  psi()    const;
+  inline  EA &       setPsi( double psi );
+
+  inline EA & set( double phi, double theta, double psi );
+
+  // ----------  Operations:
+
+  //   comparisons:
+  inline int  compare   ( const EA & ea ) const;
+
+  inline bool operator==( const EA & ea ) const;
+  inline bool operator!=( const EA & ea ) const;
+  inline bool operator< ( const EA & ea ) const;
+  inline bool operator<=( const EA & ea ) const;
+  inline bool operator> ( const EA & ea ) const;
+  inline bool operator>=( const EA & ea ) const;
+
+  //   relative comparison:
+  inline static double getTolerance();
+  inline static double setTolerance( double tol );
+
+  bool isNear ( const EA & ea, double epsilon = tolerance ) const;
+  double  howNear( const EA & ea ) const;
+
+  // ----------  I/O:
+
+  friend std::ostream & operator<<( std::ostream & os, const EA & ea );
+  friend std::istream & operator>>( std::istream & is,       EA & ea );
+
+  // ---------- Helper methods:
+
+protected:
+    double distance( const HepEulerAngles & ex ) const;
+
+  // ----------  Data members:
+protected:
+  double phi_;
+  double theta_;
+  double psi_;
+
+};  // HepEulerAngles
+
+}  // namespace CLHEP
+
+
+namespace zmpv {
+
+typedef CLHEP::HepEulerAngles EulerAngles;
+
+}  // end of namespace zmpv
+
+#define EULERANGLES_ICC
+#include "CLHEP/Vector/EulerAngles.icc"
+#undef EULERANGLES_ICC
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+
+#endif // EULERANGLES_H
Index: trunk/CLHEP/Vector/EulerAngles.icc
===================================================================
--- trunk/CLHEP/Vector/EulerAngles.icc	(revision 4)
+++ trunk/CLHEP/Vector/EulerAngles.icc	(revision 4)
@@ -0,0 +1,125 @@
+#ifndef EULERANGLES_ICC
+#error "EulerAngles.icc included without EulerAngles.h"
+#endif
+
+
+// ----------------------------------------------------------------------
+//
+// EulerAngles.icc - Inline methods for EulerAngles class.
+//
+// History:
+//    9-Apr-1997  MF	Split off from original angles.hh.  Content-free.
+//   26-Jan-1998  WEB	Fleshed out.
+//   12-Mar-1998  WEB   Gave default constructor proper default values
+//   13-Mar-1998  WEB   Simplified compare()
+//   17-Jun-1998  WEB	Added namespace support
+//   27-Jul-2000  MF	CLHEP version
+//
+// ----------------------------------------------------------------------
+
+namespace CLHEP  {
+
+
+inline HepEulerAngles::HepEulerAngles()
+: phi_( 0.0 ), theta_( 0.0 ), psi_( 0.0 )
+{}  // HepEulerAngles::HepEulerAngles()
+
+inline HepEulerAngles::HepEulerAngles ( 
+				double phi, double theta, double psi )
+				: phi_( phi ), theta_( theta ), psi_( psi )
+{}  // HepEulerAngles::HepEulerAngles()
+
+inline double HepEulerAngles::getPhi() const {
+  return  phi_;
+}  // HepEulerAngles::getPhi()
+
+inline double HepEulerAngles::phi() const {
+  return  phi_;
+}  // HepEulerAngles::phi()
+
+inline HepEulerAngles & HepEulerAngles::setPhi( double phi ) {
+  phi_ = phi;
+  return  *this;
+}  // HepEulerAngles::setPhi()
+
+inline double HepEulerAngles::getTheta() const {
+  return  theta_;
+}  // HepEulerAngles::getTheta()
+
+inline double HepEulerAngles::theta() const {
+  return  theta_;
+}  // HepEulerAngles::theta()
+
+inline HepEulerAngles & HepEulerAngles::setTheta( double theta ) {
+  theta_ = theta;
+  return  *this;
+}  // HepEulerAngles::setTheta()
+
+inline double HepEulerAngles::getPsi() const {
+  return  psi_;
+}  // HepEulerAngles::getPsi()
+
+inline double HepEulerAngles::psi() const {
+  return  psi_;
+}  // HepEulerAngles::psi()
+
+inline HepEulerAngles & HepEulerAngles::setPsi( double psi ) {
+  psi_ = psi;
+  return  *this;
+}  // HepEulerAngles::setPsi()
+
+inline HepEulerAngles & 
+	HepEulerAngles::set( double phi, double theta, double psi ) {
+  phi_ = phi, theta_ = theta, psi_ = psi;
+  return *this;
+}  // HepEulerAngles::set()
+
+
+inline int HepEulerAngles::compare( const HepEulerAngles & ea ) const {
+
+  return  phi_   < ea.phi_    ?  -1
+       :  phi_   > ea.phi_    ?  +1
+       :  theta_ < ea.theta_  ?  -1
+       :  theta_ > ea.theta_  ?  +1
+       :  psi_   < ea.psi_    ?  -1
+       :  psi_   > ea.psi_    ?  +1
+       :                          0;
+
+}  // HepEulerAngles::compare()
+
+
+inline bool HepEulerAngles::operator==( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) == 0 );
+}  // HepEulerAngles::operator==()
+
+inline bool HepEulerAngles::operator!=( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) != 0 );
+}  // HepEulerAngles::operator!=()
+
+inline bool HepEulerAngles::operator<( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) < 0 );
+}  // HepEulerAngles::operator<()
+
+inline bool HepEulerAngles::operator<=( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) <= 0 );
+}  // HepEulerAngles::operator<=()
+
+inline bool HepEulerAngles::operator>( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) > 0 );
+}  // HepEulerAngles::operator>()
+
+inline bool HepEulerAngles::operator>=( const HepEulerAngles & ea ) const {
+  return  ( compare( ea ) >= 0 );
+}  // HepEulerAngles::operator>=()
+
+inline double HepEulerAngles::getTolerance() {
+  return  tolerance;
+}  // HepEulerAngles::getTolerance()
+
+inline double HepEulerAngles::setTolerance( double tol ) {
+  double oldTolerance( tolerance );
+  tolerance = tol;
+  return  oldTolerance;
+}  // HepEulerAngles::setTolerance()
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/LorentzRotation.h
===================================================================
--- trunk/CLHEP/Vector/LorentzRotation.h	(revision 4)
+++ trunk/CLHEP/Vector/LorentzRotation.h	(revision 4)
@@ -0,0 +1,388 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// $Id: LorentzRotation.h,v 1.1 2008-06-04 14:14:58 demin Exp $
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepLorentzRotation class for performing 
+// Lorentz transformations (rotations and boosts) on objects of the
+// HepLorentzVector class.
+//
+// HepLorentzRotation is a concrete implementation of Hep4RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// ThreeVector.h, LorentzVector.h
+// Rotation.h, Boost.h
+//
+// .SS Author
+// Leif Lonnblad, Mark Fischler
+
+#ifndef HEP_LORENTZROTATION_H
+#define HEP_LORENTZROTATION_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/Rotation.h" 
+#include "CLHEP/Vector/Boost.h" 
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP {
+
+// Global methods
+
+inline HepLorentzRotation inverseOf ( const HepLorentzRotation & lt );
+HepLorentzRotation operator * (const HepRotation & r,
+                                        const HepLorentzRotation & lt);
+HepLorentzRotation operator * (const HepRotationX & r,
+                                        const HepLorentzRotation & lt);
+HepLorentzRotation operator * (const HepRotationY & r,
+                                        const HepLorentzRotation & lt);
+HepLorentzRotation operator * (const HepRotationZ & r,
+                                        const HepLorentzRotation & lt);
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepLorentzRotation {
+
+public:
+  // ----------  Identity HepLorentzRotation:
+
+  static const HepLorentzRotation IDENTITY;
+
+  // ----------  Constructors and Assignment:
+
+  inline HepLorentzRotation();
+  // Default constructor. Gives a unit matrix.
+
+  inline  HepLorentzRotation       (const HepLorentzRotation & r);
+  // Copy constructor.
+
+  inline           HepLorentzRotation (const HepRotation  & r);
+  inline  explicit HepLorentzRotation (const HepRotationX & r);
+  inline  explicit HepLorentzRotation (const HepRotationY & r);
+  inline  explicit HepLorentzRotation (const HepRotationZ & r);
+  inline           HepLorentzRotation (const HepBoost  &    b);
+  inline  explicit HepLorentzRotation (const HepBoostX &    b);
+  inline  explicit HepLorentzRotation (const HepBoostY &    b);
+  inline  explicit HepLorentzRotation (const HepBoostZ &    b);
+  // Constructors from special cases.  
+
+  inline HepLorentzRotation & operator = (const HepLorentzRotation & m);
+  inline HepLorentzRotation & operator = (const HepRotation        & m);
+  inline HepLorentzRotation & operator = (const HepBoost           & m);
+  // Assignment.
+
+         HepLorentzRotation & set (double bx, double by, double bz);
+  inline HepLorentzRotation & set (const Hep3Vector & p);
+  inline HepLorentzRotation & set (const HepRotation  & r);
+  inline HepLorentzRotation & set (const HepRotationX & r);
+  inline HepLorentzRotation & set (const HepRotationY & r);
+  inline HepLorentzRotation & set (const HepRotationZ & r);
+  inline HepLorentzRotation & set (const HepBoost & boost);
+  inline HepLorentzRotation & set (const HepBoostX & boost);
+  inline HepLorentzRotation & set (const HepBoostY & boost);
+  inline HepLorentzRotation & set (const HepBoostZ & boost);
+  inline HepLorentzRotation (double bx, double by, double bz);
+  inline HepLorentzRotation (const Hep3Vector & p);
+  // Other Constructors giving a Lorentz-boost.
+
+         HepLorentzRotation & set( const HepBoost & B, const HepRotation & R );
+  inline HepLorentzRotation (      const HepBoost & B, const HepRotation & R );
+  //   supply B and R:  T = B R:
+
+         HepLorentzRotation & set( const HepRotation & R, const HepBoost & B );
+  inline HepLorentzRotation (      const HepRotation & R, const HepBoost & B );
+  //   supply R and B:  T = R B:
+
+  HepLorentzRotation ( const HepLorentzVector & col1,
+		       const HepLorentzVector & col2,
+		       const HepLorentzVector & col3,
+		       const HepLorentzVector & col4 );
+  // Construct from four *orthosymplectic* LorentzVectors for the columns:
+	// NOTE:
+        //      This constructor, and the two set methods below,
+        //      will check that the columns (or rows) form an orthosymplectic
+        //      matrix, and will adjust values so that this relation is
+        //      as exact as possible.
+	//	Orthosymplectic means the dot product USING THE METRIC
+	//	of two different coumns will be 0, and of a column with
+	//	itself will be one. 
+
+  HepLorentzRotation & set( const HepLorentzVector & col1,
+                            const HepLorentzVector & col2,
+                            const HepLorentzVector & col3,
+                            const HepLorentzVector & col4 );
+  //   supply four *orthosymplectic* HepLorentzVectors for the columns
+
+  HepLorentzRotation & setRows( const HepLorentzVector & row1,
+                                const HepLorentzVector & row2,
+                                const HepLorentzVector & row3,
+                                const HepLorentzVector & row4 );
+  //   supply four *orthosymplectic* HepLorentzVectors for the columns
+
+  inline HepLorentzRotation & set( const HepRep4x4 & rep );
+  inline HepLorentzRotation      ( const HepRep4x4 & rep );
+  //   supply a HepRep4x4 structure (16 numbers)
+  // WARNING:
+  //            This constructor and set method will assume the
+  //            HepRep4x4 supplied is in fact an orthosymplectic matrix.
+  //            No checking or correction is done.  If you are
+  //            not certain the matrix is orthosymplectic, break it
+  //            into four HepLorentzVector columns and use the form
+  //            HepLorentzRotation (col1, col2, col3, col4)
+
+  // ----------  Accessors:
+
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double xt() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double yt() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  inline double tt() const;
+  // Elements of the matrix.
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  inline HepLorentzVector col4() const;
+  // orthosymplectic column vectors
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  inline HepLorentzVector row4() const;
+  // orthosymplectic row vectors
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation:
+
+  // ------------  Subscripting:
+
+  class HepLorentzRotation_row {
+  public:
+    inline HepLorentzRotation_row(const HepLorentzRotation &, int);
+    inline double operator [] (int) const;
+  private:
+    const HepLorentzRotation & rr;
+    int ii;
+  };
+  // Helper class for implemention of C-style subscripting r[i][j] 
+
+  inline const HepLorentzRotation_row operator [] (int) const; 
+  // Returns object of the helper class for C-style subscripting r[i][j]
+
+  double operator () (int, int) const;
+  // Fortran-style subscripting: returns (i,j) element of the matrix.
+
+  // ----------  Decomposition:
+
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  void decompose (HepBoost   & boost, HepRotation  & rotation) const;
+  // Find B and R such that L = B*R
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  void decompose (HepRotation  & rotation, HepBoost   & boost) const;
+  // Find R and B such that L = R*B 
+
+  // ----------  Comparisons:
+
+  int compare( const HepLorentzRotation & m  ) const;
+  // Dictionary-order comparison, in order tt,tz,...zt,zz,zy,zx,yt,yz,...,xx
+  // Used in operator<, >, <=, >=
+
+  inline bool operator == (const HepLorentzRotation &) const;
+  inline bool operator != (const HepLorentzRotation &) const;
+  inline bool operator <= (const HepLorentzRotation &) const;
+  inline bool operator >= (const HepLorentzRotation &) const;
+  inline bool operator <  (const HepLorentzRotation &) const;
+  inline bool operator >  (const HepLorentzRotation &) const;
+
+  inline bool isIdentity() const;
+  // Returns true if the Identity matrix.
+
+  double distance2( const HepBoost & b  ) const;
+  double distance2( const HepRotation & r  ) const;
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // Decomposes L = B*R, returns the sum of distance2 for B and R.
+
+  double howNear(   const HepBoost & b ) const;
+  double howNear(   const HepRotation & r) const;
+  double howNear(   const HepLorentzRotation & lt ) const;
+
+  bool isNear(const HepBoost & b,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(const HepRotation & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear(const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const;
+  // distance2 (IDENTITY), which involves decomposing into B and R and summing 
+  // norm2 for the individual B and R parts. 
+
+  void rectify();
+  // non-const but logically moot correction for accumulated roundoff errors
+        // rectify averages the matrix with the orthotranspose of its actual
+        // inverse (absent accumulated roundoff errors, the orthotranspose IS
+        // the inverse)); this removes to first order those errors.
+        // Then it formally decomposes that, extracts axis and delta for its
+	// Rotation part, forms a LorentzRotation from a true HepRotation 
+	// with those values of axis and delta, times the true Boost
+	// with that boost vector.
+
+  // ---------- Application:
+
+  inline HepLorentzVector vectorMultiplication(const HepLorentzVector&) const;
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  inline HepLorentzVector operator* ( const HepLorentzVector & p ) const;
+  // Multiplication with a Lorentz Vector.
+
+  // ---------- Operations in the group of 4-Rotations
+
+  HepLorentzRotation matrixMultiplication(const HepRep4x4 & m) const;
+
+  inline HepLorentzRotation operator * (const HepBoost & b) const;
+  inline HepLorentzRotation operator * (const HepRotation & r) const;
+  inline HepLorentzRotation operator * (const HepLorentzRotation & lt) const;
+  // Product of two Lorentz Rotations (this) * lt - matrix multiplication  
+
+  inline  HepLorentzRotation & operator *= (const HepBoost & b);
+  inline  HepLorentzRotation & operator *= (const HepRotation & r);
+  inline  HepLorentzRotation & operator *= (const HepLorentzRotation & lt);
+  inline  HepLorentzRotation & transform   (const HepBoost & b);
+  inline  HepLorentzRotation & transform   (const HepRotation & r);
+  inline  HepLorentzRotation & transform   (const HepLorentzRotation & lt);
+  // Matrix multiplication.
+  // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
+
+  // Here there is an opportunity for speedup by providing specialized forms
+  // of lt * r and lt * b where r is a RotationX Y or Z or b is a BoostX Y or Z
+  // These are, in fact, provided below for the transform() methods.
+
+  HepLorentzRotation & rotateX(double delta);
+  // Rotation around the x-axis; equivalent to LT = RotationX(delta) * LT
+
+  HepLorentzRotation & rotateY(double delta);
+  // Rotation around the y-axis; equivalent to LT = RotationY(delta) * LT
+
+  HepLorentzRotation & rotateZ(double delta);
+  // Rotation around the z-axis; equivalent to LT = RotationZ(delta) * LT
+
+  inline HepLorentzRotation & rotate(double delta, const Hep3Vector& axis);
+  inline HepLorentzRotation & rotate(double delta, const Hep3Vector *axis);
+  // Rotation around specified vector - LT = Rotation(delta,axis)*LT
+
+  HepLorentzRotation & boostX(double beta);
+  // Pure boost along the x-axis; equivalent to LT = BoostX(beta) * LT
+
+  HepLorentzRotation & boostY(double beta);
+  // Pure boost along the y-axis; equivalent to LT = BoostX(beta) * LT
+
+  HepLorentzRotation & boostZ(double beta);
+  // Pure boost along the z-axis; equivalent to LT = BoostX(beta) * LT
+
+  inline HepLorentzRotation & boost(double, double, double);
+  inline HepLorentzRotation & boost(const Hep3Vector &);
+  // Lorenz boost.
+
+  inline HepLorentzRotation inverse() const;
+  // Return the inverse.
+
+  inline HepLorentzRotation & invert();
+  // Inverts the LorentzRotation matrix.
+
+  // ---------- I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+  // Aligned six-digit-accurate output of the transformation matrix. 
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol); 
+
+  friend HepLorentzRotation inverseOf ( const HepLorentzRotation & lt );
+
+protected:
+
+  inline HepLorentzRotation
+       (double mxx, double mxy, double mxz, double mxt,
+	double myx, double myy, double myz, double myt,
+	double mzx, double mzy, double mzz, double mzt,
+	double mtx, double mty, double mtz, double mtt);
+  // Protected constructor.
+  // DOES NOT CHECK FOR VALIDITY AS A LORENTZ TRANSFORMATION.
+
+  inline void setBoost(double, double, double);
+  // Set elements according to a boost vector.
+
+  double mxx, mxy, mxz, mxt,
+            myx, myy, myz, myt,
+            mzx, mzy, mzz, mzt,
+            mtx, mty, mtz, mtt;
+  // The matrix elements.
+
+};  // HepLorentzRotation
+
+inline std::ostream & operator<<
+		( std::ostream & os, const  HepLorentzRotation& lt ) 
+  {return lt.print(os);}
+
+inline bool operator==(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt==r; }
+inline bool operator!=(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt!=r; }
+inline bool operator<=(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt<=r; }
+inline bool operator>=(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt>=r; }
+inline bool operator<(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt<r; }
+inline bool operator>(const HepRotation &r, const HepLorentzRotation & lt)
+  { return lt>r; }
+
+inline bool operator==(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt==b; }
+inline bool operator!=(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt!=b; }
+inline bool operator<=(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt<=b; }
+inline bool operator>=(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt>=b; }
+inline bool operator<(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt<b; }
+inline bool operator>(const HepBoost &b, const HepLorentzRotation & lt)
+  { return lt>b; }
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/LorentzRotation.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_LORENTZROTATION_H */
+
Index: trunk/CLHEP/Vector/LorentzRotation.icc
===================================================================
--- trunk/CLHEP/Vector/LorentzRotation.icc	(revision 4)
+++ trunk/CLHEP/Vector/LorentzRotation.icc	(revision 4)
@@ -0,0 +1,380 @@
+// -*- C++ -*-
+// $Id: LorentzRotation.icc,v 1.1 2008-06-04 14:14:58 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepLorentzRotation class
+//
+
+namespace CLHEP {
+
+// ----------  Constructors and Assignment:
+
+inline HepLorentzRotation::HepLorentzRotation() :
+    mxx(1.0), mxy(0.0), mxz(0.0), mxt(0.0),
+    myx(0.0), myy(1.0), myz(0.0), myt(0.0),
+    mzx(0.0), mzy(0.0), mzz(1.0), mzt(0.0),
+    mtx(0.0), mty(0.0), mtz(0.0), mtt(1.0) {}
+
+inline HepLorentzRotation::HepLorentzRotation(const HepLorentzRotation & r) :
+    mxx(r.mxx), mxy(r.mxy), mxz(r.mxz), mxt(r.mxt),
+    myx(r.myx), myy(r.myy), myz(r.myz), myt(r.myt),
+    mzx(r.mzx), mzy(r.mzy), mzz(r.mzz), mzt(r.mzt),
+    mtx(r.mtx), mty(r.mty), mtz(r.mtz), mtt(r.mtt) {}
+
+inline HepLorentzRotation::HepLorentzRotation(const HepRotation & r) {
+    set (r.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepRotationX & r) {
+    set (r.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepRotationY & r) {
+    set (r.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepRotationZ & r) {
+    set (r.rep4x4());
+}
+
+inline HepLorentzRotation::HepLorentzRotation(const HepBoost & b) {
+    set (b.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepBoostX & b) {
+    set (b.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepBoostY & b) {
+    set (b.rep4x4());
+}
+inline HepLorentzRotation::HepLorentzRotation(const HepBoostZ & b) {
+    set (b.rep4x4());
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::operator = (const HepLorentzRotation & r) {
+  mxx = r.mxx; mxy = r.mxy; mxz = r.mxz; mxt = r.mxt;
+  myx = r.myx; myy = r.myy; myz = r.myz; myt = r.myt;
+  mzx = r.mzx; mzy = r.mzy; mzz = r.mzz; mzt = r.mzt;
+  mtx = r.mtx; mty = r.mty; mtz = r.mtz; mtt = r.mtt;
+  return *this;
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::operator = (const HepRotation & m) {
+  return set (m.rep4x4());
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::operator = (const HepBoost & m) {
+  return set (m.rep4x4());
+}
+
+HepLorentzRotation & HepLorentzRotation::set (const Hep3Vector & p) {
+  return set (p.x(), p.y(), p.z());
+}
+
+inline HepLorentzRotation & HepLorentzRotation::set (const HepRotation & r) {
+  return set (r.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepRotationX & r) {
+  return set (r.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepRotationY & r) {
+  return set (r.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepRotationZ & r) {
+  return set (r.rep4x4());
+}
+
+inline HepLorentzRotation & HepLorentzRotation::set (const HepBoost & boost) {
+  return set (boost.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepBoostX & boost) {
+  return set (boost.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepBoostY & boost) {
+  return set (boost.rep4x4());
+}
+inline HepLorentzRotation & HepLorentzRotation::set (const HepBoostZ & boost) {
+  return set (boost.rep4x4());
+}
+
+inline HepLorentzRotation::HepLorentzRotation(double bx,
+                                              double by,
+                                              double bz) 
+{
+  set(bx, by, bz);
+}
+
+inline HepLorentzRotation::HepLorentzRotation(const Hep3Vector & p) 
+{
+  set(p.x(), p.y(), p.z());
+}
+
+inline HepLorentzRotation::HepLorentzRotation(
+		const HepBoost & B, const HepRotation & R)
+{
+  set(B, R);
+}
+
+inline HepLorentzRotation::HepLorentzRotation( 
+		const HepRotation & R, const HepBoost & B) 
+{
+  set(R, B);
+}
+
+inline HepLorentzRotation & HepLorentzRotation::set( const HepRep4x4 & rep ) {
+  mxx=rep.xx_;  mxy=rep.xy_;  mxz=rep.xz_;  mxt=rep.xt_;
+  myx=rep.yx_;  myy=rep.yy_;  myz=rep.yz_;  myt=rep.yt_;
+  mzx=rep.zx_;  mzy=rep.zy_;  mzz=rep.zz_;  mzt=rep.zt_;
+  mtx=rep.tx_;  mty=rep.ty_;  mtz=rep.tz_;  mtt=rep.tt_;
+  return *this;
+}
+
+inline HepLorentzRotation ::HepLorentzRotation ( const HepRep4x4 & rep ) :
+    mxx(rep.xx_), mxy(rep.xy_), mxz(rep.xz_), mxt(rep.xt_),
+    myx(rep.yx_), myy(rep.yy_), myz(rep.yz_), myt(rep.yt_),
+    mzx(rep.zx_), mzy(rep.zy_), mzz(rep.zz_), mzt(rep.zt_),
+    mtx(rep.tx_), mty(rep.ty_), mtz(rep.tz_), mtt(rep.tt_) {}
+
+// - Protected methods
+
+inline HepLorentzRotation::HepLorentzRotation( 
+  double rxx, double rxy, double rxz, double rxt,
+  double ryx, double ryy, double ryz, double ryt,
+  double rzx, double rzy, double rzz, double rzt,
+  double rtx, double rty, double rtz, double rtt) : 
+    mxx(rxx), mxy(rxy), mxz(rxz), mxt(rxt),
+    myx(ryx), myy(ryy), myz(ryz), myt(ryt),
+    mzx(rzx), mzy(rzy), mzz(rzz), mzt(rzt),
+    mtx(rtx), mty(rty), mtz(rtz), mtt(rtt) {}
+
+inline void HepLorentzRotation::setBoost
+				(double bx, double by, double bz) {
+  set(bx, by, bz);
+}
+
+// ----------  Accessors:
+
+inline double HepLorentzRotation::xx() const { return mxx; }
+inline double HepLorentzRotation::xy() const { return mxy; }
+inline double HepLorentzRotation::xz() const { return mxz; }
+inline double HepLorentzRotation::xt() const { return mxt; }
+inline double HepLorentzRotation::yx() const { return myx; }
+inline double HepLorentzRotation::yy() const { return myy; }
+inline double HepLorentzRotation::yz() const { return myz; }
+inline double HepLorentzRotation::yt() const { return myt; }
+inline double HepLorentzRotation::zx() const { return mzx; }
+inline double HepLorentzRotation::zy() const { return mzy; }
+inline double HepLorentzRotation::zz() const { return mzz; }
+inline double HepLorentzRotation::zt() const { return mzt; }
+inline double HepLorentzRotation::tx() const { return mtx; }
+inline double HepLorentzRotation::ty() const { return mty; }
+inline double HepLorentzRotation::tz() const { return mtz; }
+inline double HepLorentzRotation::tt() const { return mtt; }
+
+inline HepLorentzVector HepLorentzRotation::col1() const {
+  return HepLorentzVector ( mxx, myx, mzx, mtx );
+}
+inline HepLorentzVector HepLorentzRotation::col2() const {
+  return HepLorentzVector ( mxy, myy, mzy, mty );
+}
+inline HepLorentzVector HepLorentzRotation::col3() const {
+  return HepLorentzVector ( mxz, myz, mzz, mtz );
+}
+inline HepLorentzVector HepLorentzRotation::col4() const {
+  return HepLorentzVector ( mxt, myt, mzt, mtt );
+}
+
+inline HepLorentzVector HepLorentzRotation::row1() const {
+  return HepLorentzVector ( mxx, mxy, mxz, mxt );
+}
+inline HepLorentzVector HepLorentzRotation::row2() const {
+  return HepLorentzVector ( myx, myy, myz, myt );
+}
+inline HepLorentzVector HepLorentzRotation::row3() const {
+  return HepLorentzVector ( mzx, mzy, mzz, mzt );
+}
+inline HepLorentzVector HepLorentzRotation::row4() const {
+  return HepLorentzVector ( mtx, mty, mtz, mtt );
+}
+
+inline HepRep4x4 HepLorentzRotation::rep4x4() const {
+  return HepRep4x4( mxx, mxy, mxz, mxt, 
+                    myx, myy, myz, myt,
+                    mzx, mzy, mzz, mzt,
+                    mtx, mty, mtz, mtt );
+}
+
+
+// ------------  Subscripting:
+
+inline HepLorentzRotation::HepLorentzRotation_row::HepLorentzRotation_row
+(const HepLorentzRotation & r, int i) : rr(r), ii(i) {}
+
+inline double
+HepLorentzRotation::HepLorentzRotation_row::operator [] (int jj) const {
+  return rr(ii,jj);
+}
+
+inline const HepLorentzRotation::HepLorentzRotation_row
+HepLorentzRotation::operator [] (int i) const {
+  return HepLorentzRotation_row(*this, i);
+}
+
+// ----------  Comparisons:
+
+inline bool
+HepLorentzRotation::operator == (const HepLorentzRotation & r) const {
+  return (mxx == r.xx() && mxy == r.xy() && mxz == r.xz() && mxt == r.xt() && 
+          myx == r.yx() && myy == r.yy() && myz == r.yz() && myt == r.yt() && 
+          mzx == r.zx() && mzy == r.zy() && mzz == r.zz() && mzt == r.zt() && 
+          mtx == r.tx() && mty == r.ty() && mtz == r.tz() && mtt == r.tt());
+}
+
+inline bool
+HepLorentzRotation::operator != (const HepLorentzRotation & r) const {
+  return ! operator==(r);
+}
+
+inline bool 
+HepLorentzRotation::operator < ( const HepLorentzRotation & r ) const
+        { return compare(r)< 0; }
+inline bool 
+HepLorentzRotation::operator <= ( const HepLorentzRotation & r ) const
+        { return compare(r)<=0; }
+
+inline bool 
+HepLorentzRotation::operator >= ( const HepLorentzRotation & r ) const
+        { return compare(r)>=0; }
+inline bool 
+HepLorentzRotation::operator > ( const HepLorentzRotation & r ) const
+        { return compare(r)> 0; }
+
+inline bool HepLorentzRotation::isIdentity() const {
+  return (mxx == 1.0 && mxy == 0.0 && mxz == 0.0 && mxt == 0.0 && 
+          myx == 0.0 && myy == 1.0 && myz == 0.0 && myt == 0.0 && 
+          mzx == 0.0 && mzy == 0.0 && mzz == 1.0 && mzt == 0.0 && 
+          mtx == 0.0 && mty == 0.0 && mtz == 0.0 && mtt == 1.0);
+}
+
+// ----------  Properties:
+                             
+// ---------- Application:
+
+inline HepLorentzVector
+HepLorentzRotation::vectorMultiplication(const HepLorentzVector & p) const {
+  register double x(p.x());
+  register double y(p.y());
+  register double z(p.z());
+  register double t(p.t());
+  return HepLorentzVector(mxx*x + mxy*y + mxz*z + mxt*t,
+                	  myx*x + myy*y + myz*z + myt*t,
+			  mzx*x + mzy*y + mzz*z + mzt*t,
+			  mtx*x + mty*y + mtz*z + mtt*t);
+}
+
+inline HepLorentzVector 
+HepLorentzRotation::operator() (const HepLorentzVector & w) const {
+  return vectorMultiplication(w);
+}
+
+inline HepLorentzVector
+HepLorentzRotation::operator * (const HepLorentzVector & p) const {
+  return vectorMultiplication(p);
+}
+
+// ---------- Operations in the group of 4-Rotations
+
+inline HepLorentzRotation 
+HepLorentzRotation::operator * (const HepBoost & b) const {
+  return matrixMultiplication(b.rep4x4());
+}
+inline HepLorentzRotation 
+HepLorentzRotation::operator * (const HepRotation & r) const {
+  return matrixMultiplication(r.rep4x4());
+}
+inline HepLorentzRotation 
+HepLorentzRotation::operator * (const HepLorentzRotation & lt) const {
+  return matrixMultiplication(lt.rep4x4());
+}
+ 
+inline HepLorentzRotation &
+HepLorentzRotation::operator *= (const HepBoost & b) {
+  return *this = matrixMultiplication(b.rep4x4());
+}
+inline HepLorentzRotation &
+HepLorentzRotation::operator *= (const HepRotation & r) {
+  return *this = matrixMultiplication(r.rep4x4());
+}
+inline HepLorentzRotation &
+HepLorentzRotation::operator *= (const HepLorentzRotation & lt) {
+  return *this = matrixMultiplication(lt.rep4x4());
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::transform   (const HepBoost & b) {
+  return *this = HepLorentzRotation(b).matrixMultiplication(rep4x4());
+}
+inline HepLorentzRotation &
+HepLorentzRotation::transform   (const HepRotation & r) {
+  return *this = HepLorentzRotation(r).matrixMultiplication(rep4x4());
+}
+inline HepLorentzRotation &
+HepLorentzRotation::transform   (const HepLorentzRotation & lt) {
+  return *this = lt.matrixMultiplication(rep4x4());
+}
+
+
+
+
+
+
+inline HepLorentzRotation &
+HepLorentzRotation::rotate(double angle, const Hep3Vector & axis) {
+  return transform(HepRotation().rotate(angle, axis));
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::rotate(double angle, const Hep3Vector * axis) {
+  return transform(HepRotation().rotate(angle, axis));
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::boost(double bx, double by, double bz) {
+  return transform(HepLorentzRotation(bx, by, bz));
+}
+
+inline HepLorentzRotation &
+HepLorentzRotation::boost(const Hep3Vector & b) {
+  return transform(HepLorentzRotation(b));
+}
+
+inline HepLorentzRotation HepLorentzRotation::inverse() const {
+  return HepLorentzRotation( mxx,  myx,  mzx, -mtx,
+                             mxy,  myy,  mzy, -mty,
+                             mxz,  myz,  mzz, -mtz,
+                            -mxt, -myt, -mzt,  mtt );
+}
+
+inline HepLorentzRotation & HepLorentzRotation::invert() {
+  return *this = inverse();
+}
+
+inline HepLorentzRotation inverseOf ( const HepLorentzRotation & lt ) {
+  return HepLorentzRotation( 
+	 HepRep4x4(
+			     lt.mxx,  lt.myx,  lt.mzx, -lt.mtx,
+                             lt.mxy,  lt.myy,  lt.mzy, -lt.mty,
+                             lt.mxz,  lt.myz,  lt.mzz, -lt.mtz,
+                            -lt.mxt, -lt.myt, -lt.mzt,  lt.mtt )  );
+}
+
+inline double HepLorentzRotation::getTolerance() { 
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepLorentzRotation::setTolerance(double tol) { 
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/LorentzVector.h
===================================================================
--- trunk/CLHEP/Vector/LorentzVector.h	(revision 4)
+++ trunk/CLHEP/Vector/LorentzVector.h	(revision 4)
@@ -0,0 +1,580 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// $Id: LorentzVector.h,v 1.1 2008-06-04 14:14:58 demin Exp $
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// HepLorentzVector is a Lorentz vector consisting of Hep3Vector and
+// double components. Lorentz transformations (rotations and boosts)
+// of these vectors are perfomed by multiplying with objects of
+// the HepLorenzRotation class.
+//
+// .SS See Also
+// ThreeVector.h, Rotation.h, LorentzRotation.h
+//
+// .SS Authors
+// Leif Lonnblad and Anders Nilsson. Modified by Evgueni Tcherniaev, Mark Fischler
+//
+
+#ifndef HEP_LORENTZVECTOR_H
+#define HEP_LORENTZVECTOR_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include <iostream>
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/ThreeVector.h"
+
+namespace CLHEP {
+
+// Declarations of classes and global methods
+class HepLorentzVector;
+class HepLorentzRotation;
+class HepRotation;
+class HepAxisAngle;
+class HepEulerAngles;
+class Tcomponent;
+HepLorentzVector rotationXOf( const HepLorentzVector & vec, double delta );
+HepLorentzVector rotationYOf( const HepLorentzVector & vec, double delta );
+HepLorentzVector rotationZOf( const HepLorentzVector & vec, double delta );
+HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const Hep3Vector & axis, double delta );
+HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const HepAxisAngle & ax );
+HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const HepEulerAngles & e );
+HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, double phi,
+                                    double theta,
+                                    double psi );
+inline 
+HepLorentzVector  boostXOf( const HepLorentzVector & vec, double beta );
+inline 
+HepLorentzVector  boostYOf( const HepLorentzVector & vec, double beta );
+inline 
+HepLorentzVector  boostZOf( const HepLorentzVector & vec, double beta );
+inline HepLorentzVector  boostOf
+    ( const HepLorentzVector & vec, const Hep3Vector & betaVector );
+inline HepLorentzVector  boostOf
+    ( const HepLorentzVector & vec, const Hep3Vector & axis,  double beta );
+
+enum ZMpvMetric_t { TimePositive, TimeNegative };
+
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepLorentzVector {
+
+public:
+
+  enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES };
+  // Safe indexing of the coordinates when using with matrices, arrays, etc.
+  // (BaBar)
+
+  inline HepLorentzVector(double x, double y,
+			  double z, double t);
+  // Constructor giving the components x, y, z, t.
+
+  inline HepLorentzVector(double x, double y, double z);
+  // Constructor giving the components x, y, z with t-component set to 0.0.
+
+  inline HepLorentzVector(double t);
+  // Constructor giving the t-component with x, y and z set to 0.0.
+
+  inline HepLorentzVector();
+  // Default constructor with x, y, z and t set to 0.0.
+
+  inline HepLorentzVector(const Hep3Vector & p, double e);
+  inline HepLorentzVector(double e, const Hep3Vector & p);
+  // Constructor giving a 3-Vector and a time component.
+
+  inline HepLorentzVector(const HepLorentzVector &);
+  // Copy constructor.
+
+  inline ~HepLorentzVector();
+  // The destructor.
+
+  inline operator const Hep3Vector & () const;
+  inline operator Hep3Vector & ();
+  // Conversion (cast) to Hep3Vector.
+
+  inline double x() const;
+  inline double y() const;
+  inline double z() const;
+  inline double t() const;
+  // Get position and time.
+
+  inline void setX(double);
+  inline void setY(double);
+  inline void setZ(double);
+  inline void setT(double);
+  // Set position and time.
+
+  inline double px() const;
+  inline double py() const;
+  inline double pz() const;
+  inline double e() const;
+  // Get momentum and energy.
+
+  inline void setPx(double);
+  inline void setPy(double);
+  inline void setPz(double);
+  inline void setE(double);
+  // Set momentum and energy.
+
+  inline Hep3Vector vect() const;
+  // Get spatial component. 
+
+  inline void setVect(const Hep3Vector &);
+  // Set spatial component. 
+
+  inline double theta() const;
+  inline double cosTheta() const;
+  inline double phi() const;
+  inline double rho() const;
+  // Get spatial vector components in spherical coordinate system.
+
+  inline void setTheta(double);
+  inline void setPhi(double);
+  inline void setRho(double);
+  // Set spatial vector components in spherical coordinate system.
+
+  double operator () (int) const;
+  inline double operator [] (int) const;
+  // Get components by index.
+
+  double & operator () (int);
+  inline double & operator [] (int);
+  // Set components by index.
+
+  inline HepLorentzVector & operator = (const HepLorentzVector &);
+  // Assignment. 
+
+  inline HepLorentzVector   operator +  (const HepLorentzVector &) const;
+  inline HepLorentzVector & operator += (const HepLorentzVector &);
+  // Additions.
+
+  inline HepLorentzVector   operator -  (const HepLorentzVector &) const;
+  inline HepLorentzVector & operator -= (const HepLorentzVector &);
+  // Subtractions.
+
+  inline HepLorentzVector operator - () const;
+  // Unary minus.
+
+  inline HepLorentzVector & operator *= (double);
+         HepLorentzVector & operator /= (double);
+  // Scaling with real numbers.
+
+  inline bool operator == (const HepLorentzVector &) const;
+  inline bool operator != (const HepLorentzVector &) const;
+  // Comparisons.
+
+  inline double perp2() const;
+  // Transverse component of the spatial vector squared.
+
+  inline double perp() const;
+  // Transverse component of the spatial vector (R in cylindrical system).
+
+  inline void setPerp(double);
+  // Set the transverse component of the spatial vector.
+
+  inline double perp2(const Hep3Vector &) const;
+  // Transverse component of the spatial vector w.r.t. given axis squared.
+
+  inline double perp(const Hep3Vector &) const;
+  // Transverse component of the spatial vector w.r.t. given axis.
+
+  inline double angle(const Hep3Vector &) const;
+  // Angle wrt. another vector.
+
+  inline double mag2() const;
+  // Dot product of 4-vector with itself. 
+  // By default the metric is TimePositive, and mag2() is the same as m2().
+
+  inline double m2() const;
+  // Invariant mass squared.
+
+  inline double mag() const;
+  inline double m() const;
+  // Invariant mass. If m2() is negative then -sqrt(-m2()) is returned.
+
+  inline double mt2() const;
+  // Transverse mass squared.
+
+  inline double mt() const;
+  // Transverse mass.
+
+  inline double et2() const;
+  // Transverse energy squared.
+
+  inline double et() const;
+  // Transverse energy.
+
+  inline double dot(const HepLorentzVector &) const;
+  inline double operator * (const HepLorentzVector &) const;
+  // Scalar product.
+
+  inline double invariantMass2( const HepLorentzVector & w ) const;
+  // Invariant mass squared of pair of 4-vectors 
+
+  double invariantMass ( const HepLorentzVector & w ) const;
+  // Invariant mass of pair of 4-vectors 
+
+  inline void setVectMag(const Hep3Vector & spatial, double magnitude);
+  inline void setVectM(const Hep3Vector & spatial, double mass);
+  // Copy spatial coordinates, and set energy = sqrt(mass^2 + spatial^2)
+
+  inline double plus() const;
+  inline double minus() const;
+  // Returns the positive/negative light-cone component t +/- z.
+
+  Hep3Vector boostVector() const;
+  // Boost needed from rest4Vector in rest frame to form this 4-vector
+  // Returns the spatial components divided by the time component.
+
+  HepLorentzVector & boost(double, double, double);
+  inline HepLorentzVector & boost(const Hep3Vector &);
+  // Lorentz boost.
+
+  HepLorentzVector & boostX( double beta );
+  HepLorentzVector & boostY( double beta );
+  HepLorentzVector & boostZ( double beta );
+  // Boost along an axis, by magnitue beta (fraction of speed of light)
+
+  double rapidity() const;
+  // Returns the rapidity, i.e. 0.5*ln((E+pz)/(E-pz))
+
+  inline double pseudoRapidity() const;
+  // Returns the pseudo-rapidity, i.e. -ln(tan(theta/2))
+
+  inline bool isTimelike() const;
+  // Test if the 4-vector is timelike
+
+  inline bool isSpacelike() const;
+  // Test if the 4-vector is spacelike
+
+  inline bool isLightlike(double epsilon=tolerance) const;
+  // Test for lightlike is within tolerance epsilon
+
+  HepLorentzVector &  rotateX(double);
+  // Rotate the spatial component around the x-axis.
+
+  HepLorentzVector &  rotateY(double);
+  // Rotate the spatial component around the y-axis.
+
+  HepLorentzVector &  rotateZ(double);
+  // Rotate the spatial component around the z-axis.
+
+  HepLorentzVector &  rotateUz(const Hep3Vector &);
+  // Rotates the reference frame from Uz to newUz (unit vector).
+
+  HepLorentzVector & rotate(double, const Hep3Vector &);
+  // Rotate the spatial component around specified axis.
+
+  inline HepLorentzVector & operator *= (const HepRotation &);
+  inline HepLorentzVector & transform(const HepRotation &);
+  // Transformation with HepRotation.
+
+  HepLorentzVector & operator *= (const HepLorentzRotation &);
+  HepLorentzVector & transform(const HepLorentzRotation &);
+  // Transformation with HepLorenzRotation.
+
+// = = = = = = = = = = = = = = = = = = = = = = = =
+//
+// Esoteric properties and operations on 4-vectors:  
+//
+// 0 - Flexible metric convention and axial unit 4-vectors
+// 1 - Construct and set 4-vectors in various ways 
+// 2 - Synonyms for accessing coordinates and properties
+// 2a - Setting space coordinates in different ways 
+// 3 - Comparisions (dictionary, near-ness, and geometric)
+// 4 - Intrinsic properties 
+// 4a - Releativistic kinematic properties 
+// 4b - Methods combining two 4-vectors
+// 5 - Properties releative to z axis and to arbitrary directions
+// 7 - Rotations and Boosts
+//
+// = = = = = = = = = = = = = = = = = = = = = = = =
+
+// 0 - Flexible metric convention 
+
+  static ZMpvMetric_t setMetric( ZMpvMetric_t m );
+  static ZMpvMetric_t getMetric();
+
+// 1 - Construct and set 4-vectors in various ways 
+
+  inline void set        (double x, double y, double z, double  t);
+  inline void set        (double x, double y, double z, Tcomponent t);
+  inline HepLorentzVector(double x, double y, double z, Tcomponent t);
+  // Form 4-vector by supplying cartesian coordinate components
+
+  inline void set        (Tcomponent t, double x, double y, double z);
+  inline HepLorentzVector(Tcomponent t, double x, double y, double z);
+  // Deprecated because the 4-doubles form uses x,y,z,t, not t,x,y,z.
+
+  inline void set                 ( double t );
+
+  inline void set                 ( Tcomponent t );
+  inline explicit HepLorentzVector( Tcomponent t );
+  // Form 4-vector with zero space components, by supplying t component
+
+  inline void set                 ( const Hep3Vector & v );
+  inline explicit HepLorentzVector( const Hep3Vector & v );
+  // Form 4-vector with zero time component, by supplying space 3-vector 
+
+  inline HepLorentzVector & operator=( const Hep3Vector & v );
+  // Form 4-vector with zero time component, equal to space 3-vector 
+
+  inline void set ( const Hep3Vector & v, double t );
+  inline void set ( double t, const Hep3Vector & v );
+  // Set using specified space vector and time component
+
+// 2 - Synonyms for accessing coordinates and properties
+
+  inline double getX() const;
+  inline double getY() const;
+  inline double getZ() const;
+  inline double getT() const;
+  // Get position and time.
+
+  inline Hep3Vector v() const;
+  inline Hep3Vector getV() const;
+  // Get spatial component.   Same as vect.
+
+  inline void setV(const Hep3Vector &);
+  // Set spatial component.   Same as setVect.
+
+// 2a - Setting space coordinates in different ways 
+
+  inline void setV( double x, double y, double z );
+
+  inline void setRThetaPhi( double r, double theta, double phi);
+  inline void setREtaPhi( double r, double eta, double phi);
+  inline void setRhoPhiZ( double rho, double phi, double z );
+
+// 3 - Comparisions (dictionary, near-ness, and geometric)
+
+  int compare( const HepLorentzVector & w ) const;
+
+  bool operator >( const HepLorentzVector & w ) const;
+  bool operator <( const HepLorentzVector & w ) const;
+  bool operator>=( const HepLorentzVector & w ) const;
+  bool operator<=( const HepLorentzVector & w ) const;
+
+  bool   isNear ( const HepLorentzVector & w, 
+					double epsilon=tolerance ) const;
+  double howNear( const HepLorentzVector & w ) const;
+  // Is near using Euclidean measure t**2 + v**2
+
+  bool   isNearCM ( const HepLorentzVector & w, 
+					double epsilon=tolerance ) const;
+  double howNearCM( const HepLorentzVector & w ) const;
+  // Is near in CM frame:  Applicable only for two timelike HepLorentzVectors
+
+        // If w1 and w2 are already in their CM frame, then w1.isNearCM(w2)
+        // is exactly equivalent to w1.isNear(w2).
+        // If w1 and w2 have T components of zero, w1.isNear(w2) is exactly
+        // equivalent to w1.getV().isNear(w2.v()).  
+
+  bool isParallel( const HepLorentzVector & w, 
+					double epsilon=tolerance ) const;
+  // Test for isParallel is within tolerance epsilon
+  double howParallel (const HepLorentzVector & w) const;
+
+  static double getTolerance();
+  static double setTolerance( double tol );
+  // Set the tolerance for HepLorentzVectors to be considered near
+  // The same tolerance is used for determining isLightlike, and isParallel
+
+  double deltaR(const HepLorentzVector & v) const;
+  // sqrt ( (delta eta)^2 + (delta phi)^2 ) of space part
+
+// 4 - Intrinsic properties 
+
+         double howLightlike() const;
+  // Close to zero for almost lightlike 4-vectors; up to 1.
+
+  inline double euclideanNorm2()  const;
+  // Sum of the squares of time and space components; not Lorentz invariant. 
+
+  inline double euclideanNorm()  const; 
+  // Length considering the metric as (+ + + +); not Lorentz invariant.
+
+
+// 4a - Relativistic kinematic properties 
+
+// All Relativistic kinematic properties are independent of the sense of metric
+
+  inline double restMass2() const;
+  inline double invariantMass2() const; 
+  // Rest mass squared -- same as m2()
+
+  inline double restMass() const;
+  inline double invariantMass() const; 
+  // Same as m().  If m2() is negative then -sqrt(-m2()) is returned.
+
+// The following properties are rest-frame related, 
+// and are applicable only to non-spacelike 4-vectors
+
+  HepLorentzVector rest4Vector() const;
+  // This 4-vector, boosted into its own rest frame:  (0, 0, 0, m()) 
+          // The following relation holds by definition:
+          // w.rest4Vector().boost(w.boostVector()) == w
+
+  // Beta and gamma of the boost vector
+  double beta() const;
+  // Relativistic beta of the boost vector
+
+  double gamma() const;
+  // Relativistic gamma of the boost vector
+
+  inline double eta() const;
+  // Pseudorapidity (of the space part)
+
+  inline double eta(const Hep3Vector & ref) const;
+  // Pseudorapidity (of the space part) w.r.t. specified direction
+
+  double rapidity(const Hep3Vector & ref) const;
+  // Rapidity in specified direction
+
+  double coLinearRapidity() const;
+  // Rapidity, in the relativity textbook sense:  atanh (|P|/E)
+
+  Hep3Vector findBoostToCM() const;
+  // Boost needed to get to center-of-mass  frame:
+          // w.findBoostToCM() == - w.boostVector()
+          // w.boost(w.findBoostToCM()) == w.rest4Vector()
+
+  Hep3Vector findBoostToCM( const HepLorentzVector & w ) const;
+  // Boost needed to get to combined center-of-mass frame:
+          // w1.findBoostToCM(w2) == w2.findBoostToCM(w1)
+          // w.findBoostToCM(w) == w.findBoostToCM()
+
+  inline double et2(const Hep3Vector &) const;
+  // Transverse energy w.r.t. given axis squared.
+
+  inline double et(const Hep3Vector &) const;
+  // Transverse energy w.r.t. given axis.
+
+// 4b - Methods combining two 4-vectors
+
+  inline double diff2( const HepLorentzVector & w ) const;
+  // (this - w).dot(this-w); sign depends on metric choice
+
+  inline double delta2Euclidean ( const HepLorentzVector & w ) const;
+  // Euclidean norm of differnce:  (delta_T)^2  + (delta_V)^2
+
+// 5 - Properties releative to z axis and to arbitrary directions
+
+  double  plus(  const Hep3Vector & ref ) const;
+  // t + projection in reference direction
+
+  double  minus( const Hep3Vector & ref ) const;
+  // t - projection in reference direction
+
+// 7 - Rotations and boosts
+
+  HepLorentzVector & rotate ( const Hep3Vector & axis, double delta );
+  // Same as rotate (delta, axis)
+
+  HepLorentzVector & rotate ( const HepAxisAngle & ax );
+  HepLorentzVector & rotate ( const HepEulerAngles & e );
+  HepLorentzVector & rotate ( double phi,
+                              double theta,
+                              double psi );
+  // Rotate using these HepEuler angles - see Goldstein page 107 for conventions
+
+  HepLorentzVector & boost ( const Hep3Vector & axis,  double beta );
+  // Normalizes the Hep3Vector to define a direction, and uses beta to
+  // define the magnitude of the boost.
+
+  friend HepLorentzVector rotationXOf
+    ( const HepLorentzVector & vec, double delta );
+  friend HepLorentzVector rotationYOf
+    ( const HepLorentzVector & vec, double delta );
+  friend HepLorentzVector rotationZOf
+    ( const HepLorentzVector & vec, double delta );
+  friend HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const Hep3Vector & axis, double delta );
+  friend HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const HepAxisAngle & ax );
+  friend HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, const HepEulerAngles & e );
+  friend HepLorentzVector rotationOf
+    ( const HepLorentzVector & vec, double phi,
+                                    double theta,
+                                    double psi );
+
+  inline friend HepLorentzVector  boostXOf
+    ( const HepLorentzVector & vec, double beta );
+  inline friend HepLorentzVector  boostYOf
+    ( const HepLorentzVector & vec, double beta );
+  inline friend HepLorentzVector  boostZOf
+    ( const HepLorentzVector & vec, double beta );
+  inline friend HepLorentzVector  boostOf
+    ( const HepLorentzVector & vec, const Hep3Vector & betaVector );
+  inline friend HepLorentzVector  boostOf
+    ( const HepLorentzVector & vec, const Hep3Vector & axis,  double beta );
+ 
+private:
+
+  Hep3Vector pp;
+  double  ee;
+
+  static double tolerance;
+  static double metric;
+
+};  // HepLorentzVector
+
+// 8 - Axial Unit 4-vectors
+
+static const HepLorentzVector X_HAT4 = HepLorentzVector( 1, 0, 0, 0 );
+static const HepLorentzVector Y_HAT4 = HepLorentzVector( 0, 1, 0, 0 );
+static const HepLorentzVector Z_HAT4 = HepLorentzVector( 0, 0, 1, 0 );
+static const HepLorentzVector T_HAT4 = HepLorentzVector( 0, 0, 0, 1 );
+
+// Global methods
+
+std::ostream & operator << (std::ostream &, const HepLorentzVector &);
+// Output to a stream.
+
+std::istream & operator >> (std::istream &, HepLorentzVector &);
+// Input from a stream.
+
+typedef HepLorentzVector HepLorentzVectorD;
+typedef HepLorentzVector HepLorentzVectorF;
+
+inline HepLorentzVector operator * (const HepLorentzVector &, double a);
+inline HepLorentzVector operator * (double a, const HepLorentzVector &);
+// Scaling LorentzVector with a real number
+
+       HepLorentzVector operator / (const HepLorentzVector &, double a);
+// Dividing LorentzVector by a real number
+
+// Tcomponent definition:
+
+// Signature protection for 4-vector constructors taking 4 components
+class Tcomponent {
+private:
+  double t_;
+public:
+  explicit Tcomponent(double t) : t_(t) {}
+  operator double() const { return t_; }
+};  // Tcomponent
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/LorentzVector.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_LORENTZVECTOR_H */
Index: trunk/CLHEP/Vector/LorentzVector.icc
===================================================================
--- trunk/CLHEP/Vector/LorentzVector.icc	(revision 4)
+++ trunk/CLHEP/Vector/LorentzVector.icc	(revision 4)
@@ -0,0 +1,450 @@
+// -*- C++ -*-
+// $Id: LorentzVector.icc,v 1.1 2008-06-04 14:14:58 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepLorentzVector class.
+//
+
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP {
+
+inline double HepLorentzVector::x() const { return pp.x(); }
+inline double HepLorentzVector::y() const { return pp.y(); }
+inline double HepLorentzVector::z() const { return pp.z(); }
+inline double HepLorentzVector::t() const { return ee; }
+
+inline HepLorentzVector::
+HepLorentzVector(double x, double y, double z, double t)
+  : pp(x, y, z), ee(t) {}
+
+inline HepLorentzVector:: HepLorentzVector(double x, double y, double z)
+  : pp(x, y, z), ee(0) {}
+
+inline HepLorentzVector:: HepLorentzVector(double t)
+  : pp(0, 0, 0), ee(t) {}
+
+inline HepLorentzVector:: HepLorentzVector()
+  : pp(0, 0, 0), ee(0) {}
+
+inline HepLorentzVector::HepLorentzVector(const Hep3Vector & p, double e)
+  : pp(p), ee(e) {}
+
+inline HepLorentzVector::HepLorentzVector(double e, const Hep3Vector & p)
+  : pp(p), ee(e) {}
+
+inline HepLorentzVector::HepLorentzVector(const HepLorentzVector & p)
+  : pp(p.x(), p.y(), p.z()), ee(p.t()) {}
+
+inline HepLorentzVector::~HepLorentzVector() {}
+
+inline HepLorentzVector::operator const Hep3Vector & () const {return pp;}
+inline HepLorentzVector::operator Hep3Vector & () { return pp; }
+
+inline void HepLorentzVector::setX(double a) { pp.setX(a); } 
+inline void HepLorentzVector::setY(double a) { pp.setY(a); }
+inline void HepLorentzVector::setZ(double a) { pp.setZ(a); }
+inline void HepLorentzVector::setT(double a) { ee = a;}
+
+inline double HepLorentzVector::px() const { return pp.x(); }
+inline double HepLorentzVector::py() const { return pp.y(); }
+inline double HepLorentzVector::pz() const { return pp.z(); }
+inline double HepLorentzVector::e()  const { return ee; }
+
+inline void HepLorentzVector::setPx(double a) { pp.setX(a); } 
+inline void HepLorentzVector::setPy(double a) { pp.setY(a); }
+inline void HepLorentzVector::setPz(double a) { pp.setZ(a); }
+inline void HepLorentzVector::setE(double a)  { ee = a;}
+
+inline Hep3Vector HepLorentzVector::vect() const { return pp; } 
+inline void HepLorentzVector::setVect(const Hep3Vector &p) { pp = p; } 
+
+inline double HepLorentzVector::theta() const { return pp.theta(); }
+inline double HepLorentzVector::cosTheta() const { return pp.cosTheta(); }
+inline double HepLorentzVector::phi() const { return pp.phi(); }
+inline double HepLorentzVector::rho() const { return pp.mag(); }
+
+inline void HepLorentzVector::setTheta(double a) { pp.setTheta(a); }
+inline void HepLorentzVector::setPhi(double a) { pp.setPhi(a); }
+inline void HepLorentzVector::setRho(double a) { pp.setMag(a); }
+
+double & HepLorentzVector::operator [] (int i)       { return (*this)(i); }
+double   HepLorentzVector::operator [] (int i) const { return (*this)(i); }
+
+inline HepLorentzVector &
+HepLorentzVector::operator = (const HepLorentzVector & q) {
+  pp = q.vect();
+  ee = q.t();
+  return *this;
+}
+
+inline HepLorentzVector
+HepLorentzVector::operator + (const HepLorentzVector & q) const {
+  return HepLorentzVector(x()+q.x(), y()+q.y(), z()+q.z(), t()+q.t());
+}
+
+inline HepLorentzVector &
+HepLorentzVector::operator += (const HepLorentzVector & q) {
+  pp += q.vect();
+  ee += q.t();
+  return *this;
+}
+
+inline HepLorentzVector
+HepLorentzVector::operator - (const HepLorentzVector & q) const {
+  return HepLorentzVector(x()-q.x(), y()-q.y(), z()-q.z(), t()-q.t());
+}
+
+inline HepLorentzVector &
+HepLorentzVector::operator -= (const HepLorentzVector & q) {
+  pp -= q.vect();
+  ee -= q.t();
+  return *this;
+}
+
+inline HepLorentzVector HepLorentzVector::operator - () const {
+  return HepLorentzVector(-x(), -y(), -z(), -t());
+}
+
+inline HepLorentzVector& HepLorentzVector::operator *= (double a) {
+  pp *= a;
+  ee *= a;
+  return *this;
+}
+
+inline bool
+HepLorentzVector::operator == (const HepLorentzVector & q) const {
+  return (vect()==q.vect() && t()==q.t());
+}
+
+inline bool
+HepLorentzVector::operator != (const HepLorentzVector & q) const {
+  return (vect()!=q.vect() || t()!=q.t());
+}
+
+inline double HepLorentzVector::perp2() const   { return pp.perp2(); }
+inline double HepLorentzVector::perp()  const   { return pp.perp(); }
+inline void HepLorentzVector::setPerp(double a) { pp.setPerp(a); }
+
+inline double HepLorentzVector::perp2(const Hep3Vector &v) const {
+  return pp.perp2(v);
+}
+
+inline double HepLorentzVector::perp(const Hep3Vector &v) const {
+  return pp.perp(v);
+}
+
+inline double HepLorentzVector::angle(const Hep3Vector &v) const {
+  return pp.angle(v);
+}
+
+inline double HepLorentzVector::mag2() const {
+#if defined USING_VISUAL
+  // kludge for problem building Windows DLL
+  double r = metric*(t()*t() - pp.mag2());
+  return r;
+#else
+  return metric*(t()*t() - pp.mag2());
+#endif
+}
+
+inline double HepLorentzVector::mag() const {
+  double mm = m2();
+  return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm);
+}
+
+inline double HepLorentzVector::m2() const { 
+  return t()*t() - pp.mag2();
+}
+
+inline double HepLorentzVector::m() const { return mag(); }
+
+inline double HepLorentzVector::mt2() const {
+  return e()*e() - pz()*pz();
+}
+
+inline double HepLorentzVector::mt() const {
+  double mm = mt2();
+  return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm);
+}
+
+inline double HepLorentzVector::et2() const {
+  double pt2 = pp.perp2();
+  return pt2 == 0 ? 0 : e()*e() * pt2/(pt2+z()*z());
+}
+
+inline double HepLorentzVector::et() const {
+  double etet = et2();
+  return e() < 0.0 ? -std::sqrt(etet) : std::sqrt(etet);
+}
+
+inline double HepLorentzVector::et2(const Hep3Vector & v) const {
+  double pt2 = pp.perp2(v);
+  double pv = pp.dot(v.unit());
+  return pt2 == 0 ? 0 : e()*e() * pt2/(pt2+pv*pv);
+}
+
+inline double HepLorentzVector::et(const Hep3Vector & v) const {
+  double etet = et2(v);
+  return e() < 0.0 ? -std::sqrt(etet) : std::sqrt(etet);
+}
+
+inline void 
+HepLorentzVector::setVectMag(const Hep3Vector & spatial, double magnitude) {
+  setVect(spatial);
+  setT(std::sqrt(magnitude * magnitude + spatial * spatial));
+}
+
+inline void 
+HepLorentzVector::setVectM(const Hep3Vector & spatial, double mass) {
+  setVectMag(spatial, mass);
+}
+
+inline double HepLorentzVector::dot(const HepLorentzVector & q) const {
+#if defined USING_VISUAL
+  // kludge for problem building Windows DLL
+  double r = metric*(t()*q.t() - z()*q.z() - y()*q.y() - x()*q.x());
+  return r;
+#else
+  return metric*(t()*q.t() - z()*q.z() - y()*q.y() - x()*q.x());
+#endif
+}
+
+inline double
+HepLorentzVector::operator * (const HepLorentzVector & q) const {
+  return dot(q);
+}
+
+inline double HepLorentzVector::plus() const {
+  return t() + z();
+}
+
+inline double HepLorentzVector::minus() const {
+  return t() - z();
+}
+
+inline HepLorentzVector & HepLorentzVector::boost(const Hep3Vector & b) {
+  return boost(b.x(), b.y(), b.z());
+}
+
+inline double HepLorentzVector::pseudoRapidity() const {
+  return pp.pseudoRapidity();
+}
+
+inline double HepLorentzVector::eta() const {
+  return pp.pseudoRapidity();
+}
+
+inline double HepLorentzVector::eta( const Hep3Vector & ref ) const {
+  return pp.eta( ref );
+}
+
+inline HepLorentzVector &
+HepLorentzVector::operator *= (const HepRotation & m) {
+  pp.transform(m);
+  return *this;
+}
+
+inline HepLorentzVector &
+HepLorentzVector::transform(const HepRotation & m) {
+  pp.transform(m);
+  return *this;
+}
+
+inline HepLorentzVector operator * (const HepLorentzVector & p, double a) {
+  return HepLorentzVector(a*p.x(), a*p.y(), a*p.z(), a*p.t());
+}
+
+inline HepLorentzVector operator * (double a, const HepLorentzVector & p) {
+  return HepLorentzVector(a*p.x(), a*p.y(), a*p.z(), a*p.t());
+}
+
+// The following were added when ZOOM PhysicsVectors was merged in:
+
+inline HepLorentzVector::HepLorentzVector( 
+	double x, double y, double z, Tcomponent t ) :
+	pp(x, y, z), ee(t) {}
+
+inline void HepLorentzVector::set(
+	double x, double y, double z, Tcomponent t ) {
+  pp.set(x,y,z);
+  ee = t;
+}
+
+inline void HepLorentzVector::set(
+        double x, double y, double z, double t ) {
+  set (x,y,z,Tcomponent(t));
+}
+
+inline HepLorentzVector::HepLorentzVector( 
+	Tcomponent t, double x, double y, double z ) :
+        pp(x, y, z), ee(t) {}   
+
+inline void HepLorentzVector::set(
+	Tcomponent t, double x, double y, double z ) {
+  pp.set(x,y,z);
+  ee = t;
+}
+
+inline void HepLorentzVector::set( Tcomponent t ) {
+  pp.set(0, 0, 0);
+  ee = t;
+}
+
+inline void HepLorentzVector::set( double t ) {
+  pp.set(0, 0, 0);
+  ee = t;
+}
+
+inline HepLorentzVector::HepLorentzVector( Tcomponent t ) : 
+	pp(0, 0, 0), ee(t) {}
+
+inline void HepLorentzVector::set( const Hep3Vector & v ) {
+  pp = v;
+  ee = 0;
+}
+
+inline HepLorentzVector::HepLorentzVector( const Hep3Vector & v ) : 
+	pp(v), ee(0) {}
+
+inline void HepLorentzVector::setV(const Hep3Vector & v) {
+  pp = v;
+}
+
+inline HepLorentzVector & HepLorentzVector::operator=(const Hep3Vector & v) {
+  pp = v;
+  ee = 0;
+  return *this;
+}
+
+inline double HepLorentzVector::getX() const { return pp.x(); }
+inline double HepLorentzVector::getY() const { return pp.y(); }
+inline double HepLorentzVector::getZ() const { return pp.z(); }
+inline double HepLorentzVector::getT() const { return ee; }
+
+inline Hep3Vector HepLorentzVector::getV() const { return pp; } 
+inline Hep3Vector HepLorentzVector::v() const { return pp; } 
+
+inline void HepLorentzVector::set(double t, const Hep3Vector & v) {
+  pp = v;
+  ee = t;
+}
+
+inline void HepLorentzVector::set(const Hep3Vector & v, double t) {
+  pp = v;
+  ee = t;
+}
+
+inline void HepLorentzVector::setV( double x,
+             double y,
+             double z ) { pp.set(x, y, z); }
+
+inline void HepLorentzVector::setRThetaPhi 
+		( double r, double theta, double phi ) 
+                         { pp.setRThetaPhi( r, theta, phi ); }
+
+inline void HepLorentzVector::setREtaPhi 
+		( double r, double eta, double phi ) 
+                         { pp.setREtaPhi( r, eta, phi ); }
+
+inline void HepLorentzVector::setRhoPhiZ
+		( double rho, double phi, double z )
+                         { pp.setRhoPhiZ ( rho, phi, z ); }
+
+inline bool HepLorentzVector::isTimelike() const {
+  return restMass2() > 0;
+}  
+
+inline bool  HepLorentzVector::isSpacelike() const {
+  return restMass2() < 0;
+}
+
+inline bool  HepLorentzVector::isLightlike(double epsilon) const {
+  return std::fabs(restMass2()) < 2.0 * epsilon * ee * ee;
+}
+
+inline double HepLorentzVector::diff2( const HepLorentzVector & w ) const {
+#if defined USING_VISUAL
+    // kludge for problem building Windows DLL
+    double r= metric*( (ee-w.ee)*(ee-w.ee) - (pp-w.pp).mag2() );
+    return r;
+#else
+    return metric*( (ee-w.ee)*(ee-w.ee) - (pp-w.pp).mag2() );
+#endif
+}
+
+inline double HepLorentzVector::delta2Euclidean 
+					( const HepLorentzVector & w ) const {
+    return (ee-w.ee)*(ee-w.ee) + (pp-w.pp).mag2();
+}
+
+inline double HepLorentzVector::euclideanNorm2()  const {
+  return ee*ee + pp.mag2();
+}
+
+inline double HepLorentzVector::euclideanNorm()  const {
+  return std::sqrt(euclideanNorm2());
+}
+
+inline double HepLorentzVector::restMass2()      const { return m2(); }
+inline double HepLorentzVector::invariantMass2() const { return m2(); }
+
+inline double HepLorentzVector::restMass() const {
+    if( t() < 0.0 ) ZMthrowC(ZMxpvNegativeMass(
+              "E^2-p^2 < 0 for this particle. Magnitude returned."));
+    return t() < 0.0 ? -m() : m();
+}
+
+inline double HepLorentzVector::invariantMass() const {
+    if( t() < 0.0 ) ZMthrowC(ZMxpvNegativeMass(
+              "E^2-p^2 < 0 for this particle. Magnitude returned."));
+    return t() < 0.0 ? -m() : m();
+}
+
+inline double HepLorentzVector::invariantMass2
+					(const HepLorentzVector & w) const {
+  return (*this + w).m2();
+} /* invariantMass2 */
+
+//-*********
+// boostOf()
+//-*********
+
+// Each of these is a shell over a boost method.
+
+inline HepLorentzVector boostXOf
+	(const HepLorentzVector & vec, double beta) {
+  HepLorentzVector vv (vec);
+  return vv.boostX (beta);
+}
+
+inline HepLorentzVector boostYOf
+	(const HepLorentzVector & vec, double beta) {
+  HepLorentzVector vv (vec);
+  return vv.boostY (beta);
+}
+
+inline HepLorentzVector boostZOf
+	(const HepLorentzVector & vec, double beta) {
+  HepLorentzVector vv (vec);
+  return vv.boostZ (beta);
+}
+
+inline HepLorentzVector boostOf
+	(const HepLorentzVector & vec, const Hep3Vector & betaVector ) {
+  HepLorentzVector vv (vec);
+  return vv.boost (betaVector);
+}
+
+inline HepLorentzVector boostOf
+    (const HepLorentzVector & vec, const Hep3Vector & axis,  double beta) {
+  HepLorentzVector vv (vec);
+  return vv.boost (axis, beta);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/Rotation.h
===================================================================
--- trunk/CLHEP/Vector/Rotation.h	(revision 4)
+++ trunk/CLHEP/Vector/Rotation.h	(revision 4)
@@ -0,0 +1,423 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// $Id: Rotation.h,v 1.1 2008-06-04 14:14:59 demin Exp $
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepRotation class for performing rotations
+// on objects of the Hep3Vector (and HepLorentzVector) class.
+//
+// HepRotation is a concrete implementation of Hep3RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// ThreeVector.h, LorentzVector.h, LorentzRotation.h
+//
+// .SS Author
+// Leif Lonnblad, Mark Fischler
+
+#ifndef HEP_ROTATION_H
+#define HEP_ROTATION_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+#include "CLHEP/Vector/RotationX.h"
+#include "CLHEP/Vector/RotationY.h"
+#include "CLHEP/Vector/RotationZ.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP {
+
+// Declarations of classes and global methods
+class HepRotation;
+inline HepRotation inverseOf ( const HepRotation & r );
+inline HepRotation operator * (const HepRotationX & rx, const HepRotation & r);
+inline HepRotation operator * (const HepRotationY & ry, const HepRotation & r);
+inline HepRotation operator * (const HepRotationZ & rz, const HepRotation & r);
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepRotation {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepRotation();
+  // Default constructor. Gives a unit matrix.
+
+  inline HepRotation(const HepRotation  & m);
+  // Copy constructor.
+
+  inline HepRotation(const HepRotationX & m);
+  inline HepRotation(const HepRotationY & m);
+  inline HepRotation(const HepRotationZ & m);
+  // Construct from specialized rotation.
+
+  HepRotation & set( const Hep3Vector & axis, double delta );
+  HepRotation      ( const Hep3Vector & axis, double delta );
+  // Construct from axis and angle.
+
+  HepRotation & set( const HepAxisAngle & ax );
+  HepRotation      ( const HepAxisAngle & ax );
+  // Construct from AxisAngle structure.
+
+  HepRotation & set( double phi, double theta, double psi );
+  HepRotation      ( double phi, double theta, double psi );
+  // Construct from three Euler angles (in radians).
+
+  HepRotation & set( const HepEulerAngles & e );
+  HepRotation      ( const HepEulerAngles & e );
+  // Construct from EulerAngles structure.
+
+  HepRotation ( const Hep3Vector & colX,
+                const Hep3Vector & colY,
+                const Hep3Vector & colZ );
+  // Construct from three *orthogonal* unit vector columns.
+  	// NOTE:	
+  	//       This constructor, and the two set methods below, 
+	//	 will check that the columns (or rows) form an orthonormal 
+	//	 matrix, and will adjust values so that this relation is 
+	//	 as exact as possible.
+
+  HepRotation & set( const Hep3Vector & colX,
+                             const Hep3Vector & colY,
+                             const Hep3Vector & colZ );
+  //   supply three *orthogonal* unit vectors for the columns.
+
+  HepRotation & setRows( const Hep3Vector & rowX,
+                                 const Hep3Vector & rowY,
+                                 const Hep3Vector & rowZ );
+  //   supply three *orthogonal* unit vectors for the rows.
+
+  inline HepRotation & set(const HepRotationX & r);
+  inline HepRotation & set(const HepRotationY & r);
+  inline HepRotation & set(const HepRotationZ & r);
+  // set from specialized rotation.
+
+  inline  HepRotation & operator = (const HepRotation & r);
+  // Assignment.
+
+  inline  HepRotation & operator = (const HepRotationX & r);
+  inline  HepRotation & operator = (const HepRotationY & r);
+  inline  HepRotation & operator = (const HepRotationZ & r);
+  // Assignment from specialized rotation.
+
+  inline HepRotation &set( const HepRep3x3 & m );
+  inline HepRotation     ( const HepRep3x3 & m );
+  // WARNING - NO CHECKING IS DONE!
+  // Constructon directly from from a 3x3 representation,
+  // which is required to be an orthogonal matrix.
+
+  inline ~HepRotation();
+  // Trivial destructor.
+
+  // ----------  Accessors:
+
+  inline Hep3Vector colX() const;
+  inline Hep3Vector colY() const;
+  inline Hep3Vector colZ() const;
+  // orthogonal unit-length column vectors
+
+  inline Hep3Vector rowX() const;
+  inline Hep3Vector rowY() const;
+  inline Hep3Vector rowZ() const;
+  // orthogonal unit-length row vectors
+                                
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  // Elements of the rotation matrix (Geant4).
+
+  inline HepRep3x3 rep3x3() const;
+  //   3x3 representation:
+
+  // ------------  Subscripting:
+
+  class HepRotation_row {
+  public:
+    inline HepRotation_row(const HepRotation &, int);
+    inline double operator [] (int) const;
+  private:
+    const HepRotation & rr;
+    int ii;
+  };
+  // Helper class for implemention of C-style subscripting r[i][j] 
+
+  inline const HepRotation_row operator [] (int) const; 
+  // Returns object of the helper class for C-style subscripting r[i][j]
+  // i and j range from 0 to 2.  
+
+  double operator () (int, int) const;
+  // Fortran-style subscripting: returns (i,j) element of the rotation matrix.
+  // Note:  i and j still range from 0 to 2.			[Rotation.cc]
+
+  // ------------  Euler angles:
+  inline  double getPhi  () const;
+  inline  double getTheta() const;
+  inline  double getPsi  () const;
+  double    phi  () const;
+  double    theta() const;
+  double    psi  () const;
+  HepEulerAngles eulerAngles() const;
+
+  // ------------  axis & angle of rotation:
+  inline  double  getDelta() const;
+  inline  Hep3Vector getAxis () const;
+  double     delta() const;
+  Hep3Vector    axis () const;
+  HepAxisAngle  axisAngle() const;
+  void getAngleAxis(double & delta, Hep3Vector & axis) const;
+  // Returns the rotation angle and rotation axis (Geant4). 	[Rotation.cc]
+
+  // ------------- Angles of rotated axes
+  double phiX() const;
+  double phiY() const;
+  double phiZ() const;
+  double thetaX() const;
+  double thetaY() const;
+  double thetaZ() const;
+  // Return angles (RADS) made by rotated axes against original axes (Geant4).
+  //								[Rotation.cc]
+
+  // ----------  Other accessors treating pure rotation as a 4-rotation
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  //  orthosymplectic 4-vector columns - T component will be zero
+
+  inline HepLorentzVector col4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  //  orthosymplectic 4-vector rows - T component will be zero
+
+  inline HepLorentzVector row4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline double xt() const;
+  inline double yt() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  // Will be zero for this pure Rotation
+
+  inline double tt() const;
+  // Will be one for this pure Rotation
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation.
+
+  // ---------   Mutators 
+
+  void setPhi (double phi);
+  // change Euler angle phi, leaving theta and psi unchanged.
+
+  void setTheta (double theta);
+  // change Euler angle theta, leaving phi and psi unchanged.
+
+  void setPsi (double psi);
+  // change Euler angle psi, leaving theta and phi unchanged.
+
+  void setAxis (const Hep3Vector & axis);
+  // change rotation axis, leaving delta unchanged.
+
+  void setDelta (double delta);
+  // change angle of rotation, leaving rotation axis unchanged.
+
+  // ----------  Decomposition:
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  // These are trivial, as the boost vector is 0.		[RotationP.cc]
+
+  // ----------  Comparisons: 
+  
+  bool isIdentity() const;				
+  // Returns true if the identity matrix (Geant4).		[Rotation.cc]	
+
+  int compare( const HepRotation & r  ) const;
+  // Dictionary-order comparison, in order zz, zy, zx, yz, ... xx
+  // Used in operator<, >, <=, >= 
+
+  inline bool operator== ( const HepRotation & r ) const;
+  inline bool operator!= ( const HepRotation & r ) const;
+  inline bool operator<  ( const HepRotation & r ) const;
+  inline bool operator>  ( const HepRotation & r ) const;
+  inline bool operator<= ( const HepRotation & r ) const;
+  inline bool operator>= ( const HepRotation & r ) const;
+  
+  double distance2( const HepRotation &  r  ) const; 
+  // 3 - Tr ( this/r ) -- This works with RotationX, Y or Z also
+
+  double howNear( const HepRotation & r ) const;
+  bool isNear( const HepRotation & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  double distance2( const HepBoost           & lt  ) const; 
+  // 3 - Tr ( this ) + |b|^2 / (1-|b|^2) 
+  double distance2( const HepLorentzRotation & lt  ) const; 
+  // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt
+
+  double howNear( const HepBoost           & lt ) const;
+  double howNear( const HepLorentzRotation & lt ) const;
+  bool isNear( const HepBoost           & lt, 
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const; 
+  // distance2 (IDENTITY), which is 3 - Tr ( *this )
+
+  void rectify();
+  // non-const but logically moot correction for accumulated roundoff errors
+	// rectify averages the matrix with the transpose of its actual
+	// inverse (absent accumulated roundoff errors, the transpose IS
+	// the inverse)); this removes to first order those errors.
+	// Then it formally extracts axis and delta, and forms a true
+	// HepRotation with those values of axis and delta.
+
+  // ---------- Application:
+
+  inline Hep3Vector operator() (const Hep3Vector & p) const;
+  // Rotate a Hep3Vector.					
+
+  inline  Hep3Vector operator * (const Hep3Vector & p) const;
+  // Multiplication with a Hep3Vector.
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Rotate (the space part of) a HepLorentzVector.		
+
+  inline  HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a HepLorentzVector.
+
+  // ---------- Operations in the group of Rotations
+
+  inline HepRotation operator * (const HepRotation & r) const;
+  // Product of two rotations (this) * r - matrix multiplication  
+
+  inline HepRotation operator * (const HepRotationX & rx) const; 
+  inline HepRotation operator * (const HepRotationY & ry) const;
+  inline HepRotation operator * (const HepRotationZ & rz) const;
+  // Product of two rotations (this) * r - faster when specialized type 
+
+  inline  HepRotation & operator *= (const HepRotation & r);
+  inline  HepRotation & transform   (const HepRotation & r);
+  // Matrix multiplication.
+  // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
+
+  inline  HepRotation & operator *= (const HepRotationX & r);
+  inline  HepRotation & operator *= (const HepRotationY & r);
+  inline  HepRotation & operator *= (const HepRotationZ & r);
+  inline  HepRotation & transform   (const HepRotationX & r);
+  inline  HepRotation & transform   (const HepRotationY & r);
+  inline  HepRotation & transform   (const HepRotationZ & r);
+  // Matrix multiplication by specialized matrices
+
+  HepRotation & rotateX(double delta);
+  // Rotation around the x-axis; equivalent to R = RotationX(delta) * R
+
+  HepRotation & rotateY(double delta);
+  // Rotation around the y-axis; equivalent to R = RotationY(delta) * R
+
+  HepRotation & rotateZ(double delta);
+  // Rotation around the z-axis; equivalent to R = RotationZ(delta) * R
+
+         HepRotation & rotate(double delta, const Hep3Vector & axis);
+  inline HepRotation & rotate(double delta, const Hep3Vector * axis);
+  // Rotation around a specified vector.  
+  // r.rotate(d,a) is equivalent to r = Rotation(d,a) * r
+
+  HepRotation & rotateAxes(const Hep3Vector & newX,
+                           const Hep3Vector & newY,
+                           const Hep3Vector & newZ);
+  // Rotation of local axes defined by 3 orthonormal vectors (Geant4).
+  // Equivalent to r = Rotation (newX, newY, newZ) * r
+
+  inline HepRotation inverse() const;
+  // Returns the inverse.
+
+  inline HepRotation & invert();
+  // Inverts the Rotation matrix.
+
+  // ---------- I/O: 
+
+  std::ostream & print( std::ostream & os ) const;
+  // Aligned six-digit-accurate output of the  rotation matrix.	[RotationIO.cc]
+
+  // ---------- Identity Rotation:
+
+  static const HepRotation IDENTITY;
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol); 
+
+protected:
+
+  inline HepRotation(double mxx, double mxy, double mxz, 
+		     double myx, double myy, double myz,
+		     double mzx, double mzy, double mzz);
+  // Protected constructor.  
+  // DOES NOT CHECK FOR VALIDITY AS A ROTATION.
+
+  friend HepRotation operator* (const HepRotationX & rx, const HepRotation & r);
+  friend HepRotation operator* (const HepRotationY & ry, const HepRotation & r);
+  friend HepRotation operator* (const HepRotationZ & rz, const HepRotation & r);
+
+  double rxx, rxy, rxz, 
+	    ryx, ryy, ryz, 
+	    rzx, rzy, rzz;
+  // The matrix elements.
+
+private:
+  bool 
+       setCols ( const Hep3Vector & u1,	// Vectors assume to be of unit length 
+                 const Hep3Vector & u2,
+                 const Hep3Vector & u3,
+                 double u1u2,
+                 Hep3Vector & v1,		// Returned vectors
+                 Hep3Vector & v2,
+                 Hep3Vector & v3 ) const;
+  void setArbitrarily (const Hep3Vector & colX, // assumed to be of unit length
+                      Hep3Vector & v1,
+                      Hep3Vector & v2,
+                      Hep3Vector & v3) const;
+};  // HepRotation
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepRotation & r ) {return r.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/Rotation.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_ROTATION_H */
+
Index: trunk/CLHEP/Vector/Rotation.icc
===================================================================
--- trunk/CLHEP/Vector/Rotation.icc	(revision 4)
+++ trunk/CLHEP/Vector/Rotation.icc	(revision 4)
@@ -0,0 +1,348 @@
+// -*- C++ -*-
+// $Id: Rotation.icc,v 1.1 2008-06-04 14:14:59 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepRotation class
+//
+
+namespace CLHEP {
+
+// Put commonly used accessors as early as possible to avoid inlining misses:
+
+inline double HepRotation::xx() const { return rxx; }
+inline double HepRotation::xy() const { return rxy; }
+inline double HepRotation::xz() const { return rxz; }
+inline double HepRotation::yx() const { return ryx; }
+inline double HepRotation::yy() const { return ryy; }
+inline double HepRotation::yz() const { return ryz; }
+inline double HepRotation::zx() const { return rzx; }
+inline double HepRotation::zy() const { return rzy; }
+inline double HepRotation::zz() const { return rzz; }
+
+inline HepRep3x3 HepRotation::rep3x3() const {
+  return HepRep3x3 ( rxx, rxy, rxz, 
+		     ryx, ryy, ryz, 
+		     rzx, rzy, rzz );
+}
+
+inline double HepRotation::xt() const { return 0.0; }
+inline double HepRotation::yt() const { return 0.0; }
+inline double HepRotation::zt() const { return 0.0; }
+inline double HepRotation::tx() const { return 0.0; }
+inline double HepRotation::ty() const { return 0.0; }
+inline double HepRotation::tz() const { return 0.0; }
+inline double HepRotation::tt() const { return 1.0; }
+
+inline HepRep4x4 HepRotation::rep4x4() const {
+  return HepRep4x4 ( rxx, rxy, rxz, 0.0,
+		     ryx, ryy, ryz, 0.0,
+		     rzx, rzy, rzz, 0.0,
+		     0.0, 0.0, 0.0, 1.0 );
+}
+
+// Ctors etc:
+
+inline HepRotation::HepRotation() : rxx(1.0), rxy(0.0), rxz(0.0), 
+				    ryx(0.0), ryy(1.0), ryz(0.0),
+				    rzx(0.0), rzy(0.0), rzz(1.0) {}
+
+inline HepRotation::HepRotation(const HepRotation & m) : 
+	rxx(m.rxx), rxy(m.rxy), rxz(m.rxz), 
+	ryx(m.ryx), ryy(m.ryy), ryz(m.ryz),
+	rzx(m.rzx), rzy(m.rzy), rzz(m.rzz) {}
+
+inline HepRotation::HepRotation
+			(double mxx, double mxy, double mxz,
+			 double myx, double myy, double myz,
+			 double mzx, double mzy, double mzz) : 
+	rxx(mxx), rxy(mxy), rxz(mxz), 
+	ryx(myx), ryy(myy), ryz(myz),
+	rzx(mzx), rzy(mzy), rzz(mzz) {}
+
+inline HepRotation::HepRotation ( const HepRep3x3 & m ) :
+	rxx(m.xx_), rxy(m.xy_), rxz(m.xz_), 
+	ryx(m.yx_), ryy(m.yy_), ryz(m.yz_),
+	rzx(m.zx_), rzy(m.zy_), rzz(m.zz_) {}
+
+inline HepRotation::HepRotation(const HepRotationX & rx) : 
+	rxx(1.0), rxy(0.0),     rxz(0.0), 
+	ryx(0.0), ryy(rx.yy()), ryz(rx.yz()),
+	rzx(0.0), rzy(rx.zy()), rzz(rx.zz()) {}
+
+inline HepRotation::HepRotation(const HepRotationY & ry) : 
+	rxx(ry.xx()), rxy(0.0), rxz(ry.xz()), 
+	ryx(0.0),     ryy(1.0), ryz(0.0),
+	rzx(ry.zx()), rzy(0.0), rzz(ry.zz()) {}
+
+inline HepRotation::HepRotation(const HepRotationZ & rz) : 
+	rxx(rz.xx()), rxy(rz.xy()), rxz(0.0), 
+	ryx(rz.yx()), ryy(rz.yy()), ryz(0.0),
+	rzx(0.0),     rzy(0.0),     rzz(1.0) {}
+
+inline HepRotation::~HepRotation() {}
+
+// More accessors:
+
+inline HepRotation::HepRotation_row::HepRotation_row
+(const HepRotation & r, int i) : rr(r), ii(i) {}
+
+inline double HepRotation::HepRotation_row::operator [] (int jj) const {
+  return rr(ii,jj);
+}
+
+inline
+const HepRotation::HepRotation_row HepRotation::operator [] (int i) const {
+  return HepRotation_row(*this, i);
+}
+
+inline Hep3Vector HepRotation::colX() const 
+				{ return Hep3Vector ( rxx, ryx, rzx ); }
+inline Hep3Vector HepRotation::colY() const 
+				{ return Hep3Vector ( rxy, ryy, rzy ); }
+inline Hep3Vector HepRotation::colZ() const 
+				{ return Hep3Vector ( rxz, ryz, rzz ); }
+ 
+inline Hep3Vector HepRotation::rowX() const 
+				{ return Hep3Vector ( rxx, rxy, rxz ); }
+inline Hep3Vector HepRotation::rowY() const 
+				{ return Hep3Vector ( ryx, ryy, ryz ); }
+inline Hep3Vector HepRotation::rowZ() const 
+				{ return Hep3Vector ( rzx, rzy, rzz ); }
+ 
+inline HepLorentzVector HepRotation::col1() const 
+				{ return HepLorentzVector (colX(), 0); }
+inline HepLorentzVector HepRotation::col2() const
+				{ return HepLorentzVector (colY(), 0); }
+inline HepLorentzVector HepRotation::col3() const
+				{ return HepLorentzVector (colZ(), 0); }
+inline HepLorentzVector HepRotation::col4() const
+				{ return HepLorentzVector (0,0,0,1); }
+inline HepLorentzVector HepRotation::row1() const
+				{ return HepLorentzVector (rowX(), 0); }
+inline HepLorentzVector HepRotation::row2() const
+				{ return HepLorentzVector (rowY(), 0); }
+inline HepLorentzVector HepRotation::row3() const
+				{ return HepLorentzVector (rowZ(), 0); }
+inline HepLorentzVector HepRotation::row4() const
+				{ return HepLorentzVector (0,0,0,1); }
+
+inline double  HepRotation::getPhi  () const { return phi();   }
+inline double  HepRotation::getTheta() const { return theta(); }
+inline double  HepRotation::getPsi  () const { return psi();   }
+inline double  HepRotation::getDelta() const { return delta(); }
+inline Hep3Vector HepRotation::getAxis () const { return axis();  }
+
+inline HepRotation & HepRotation::operator = (const HepRotation & m) {
+  rxx = m.rxx;
+  rxy = m.rxy;
+  rxz = m.rxz;
+  ryx = m.ryx;
+  ryy = m.ryy;
+  ryz = m.ryz;
+  rzx = m.rzx;
+  rzy = m.rzy;
+  rzz = m.rzz;
+  return *this;
+}
+
+inline HepRotation & HepRotation::set(const HepRep3x3 & m) {
+  rxx = m.xx_;
+  rxy = m.xy_;
+  rxz = m.xz_;
+  ryx = m.yx_;
+  ryy = m.yy_;
+  ryz = m.yz_;
+  rzx = m.zx_;
+  rzy = m.zy_;
+  rzz = m.zz_;
+  return *this;
+}
+
+inline HepRotation & HepRotation::set(const HepRotationX & r) {
+  return (set (r.rep3x3()));
+}
+inline HepRotation & HepRotation::set(const HepRotationY & r) {
+  return (set (r.rep3x3()));
+}
+inline HepRotation & HepRotation::set(const HepRotationZ & r) {
+  return (set (r.rep3x3()));
+}
+
+inline HepRotation & HepRotation::operator= (const HepRotationX & r) {
+  return (set (r.rep3x3()));
+}
+inline HepRotation & HepRotation::operator= (const HepRotationY & r) {
+  return (set (r.rep3x3()));
+}
+inline HepRotation & HepRotation::operator= (const HepRotationZ & r) {
+  return (set (r.rep3x3()));
+}
+
+inline Hep3Vector HepRotation::operator * (const Hep3Vector & p) const {
+  return Hep3Vector(rxx*p.x() + rxy*p.y() + rxz*p.z(),
+                    ryx*p.x() + ryy*p.y() + ryz*p.z(),
+                    rzx*p.x() + rzy*p.y() + rzz*p.z());
+//  This is identical to the code in the CLHEP 1.6 version
+}
+
+inline Hep3Vector HepRotation::operator () (const Hep3Vector & p) const {
+  register double x = p.x();
+  register double y = p.y();
+  register double z = p.z();
+  return Hep3Vector(rxx*x + rxy*y + rxz*z,
+                    ryx*x + ryy*y + ryz*z,
+                    rzx*x + rzy*y + rzz*z);
+}
+
+inline HepLorentzVector
+HepRotation::operator () (const HepLorentzVector & w) const {
+  return HepLorentzVector( operator() (w.vect()), w.t() );
+}
+
+inline HepLorentzVector HepRotation::operator * 
+					(const HepLorentzVector & p) const {
+  return operator()(p);
+}
+
+inline HepRotation HepRotation::operator* (const HepRotation & r) const {
+  return HepRotation(rxx*r.rxx + rxy*r.ryx + rxz*r.rzx,
+                     rxx*r.rxy + rxy*r.ryy + rxz*r.rzy,
+                     rxx*r.rxz + rxy*r.ryz + rxz*r.rzz,
+                     ryx*r.rxx + ryy*r.ryx + ryz*r.rzx,
+                     ryx*r.rxy + ryy*r.ryy + ryz*r.rzy,
+                     ryx*r.rxz + ryy*r.ryz + ryz*r.rzz,
+                     rzx*r.rxx + rzy*r.ryx + rzz*r.rzx,
+                     rzx*r.rxy + rzy*r.ryy + rzz*r.rzy,
+                     rzx*r.rxz + rzy*r.ryz + rzz*r.rzz );
+}
+
+inline HepRotation HepRotation::operator * (const HepRotationX & rx) const {
+  double yy = rx.yy();
+  double yz = rx.yz();
+  double zy = -yz;
+  double zz =  yy;
+  return HepRotation(
+    rxx,   rxy*yy + rxz*zy,   rxy*yz + rxz*zz,
+    ryx,   ryy*yy + ryz*zy,   ryy*yz + ryz*zz,
+    rzx,   rzy*yy + rzz*zy,   rzy*yz + rzz*zz );
+}
+
+inline HepRotation HepRotation::operator * (const HepRotationY & ry) const {
+  double xx = ry.xx();
+  double xz = ry.xz();
+  double zx = -xz;
+  double zz =  xx;
+  return HepRotation(
+    rxx*xx + rxz*zx,   rxy,   rxx*xz + rxz*zz,   
+    ryx*xx + ryz*zx,   ryy,   ryx*xz + ryz*zz,   
+    rzx*xx + rzz*zx,   rzy,   rzx*xz + rzz*zz );
+}
+
+inline HepRotation HepRotation::operator * (const HepRotationZ & rz) const {
+  double xx = rz.xx();
+  double xy = rz.xy();
+  double yx = -xy;
+  double yy =  xx;
+  return HepRotation(
+    rxx*xx + rxy*yx,   rxx*xy + rxy*yy,   rxz,   
+    ryx*xx + ryy*yx,   ryx*xy + ryy*yy,   ryz,   
+    rzx*xx + rzy*yx,   rzx*xy + rzy*yy,   rzz );
+}
+
+
+inline HepRotation & HepRotation::operator *= (const HepRotation & r) {
+  return *this = (*this) * (r);
+}
+
+inline HepRotation & HepRotation::operator *= (const HepRotationX & r) {
+  return *this = (*this) * (r); }
+inline HepRotation & HepRotation::operator *= (const HepRotationY & r) {
+  return *this = (*this) * (r); }
+inline HepRotation & HepRotation::operator *= (const HepRotationZ & r) {
+  return *this = (*this) * (r); }
+
+inline HepRotation & HepRotation::transform(const HepRotation & r) {
+  return *this = r * (*this);
+}
+
+inline HepRotation & HepRotation::transform(const HepRotationX & r) {
+  return *this = r * (*this); }
+inline HepRotation & HepRotation::transform(const HepRotationY & r) {
+  return *this = r * (*this); }
+inline HepRotation & HepRotation::transform(const HepRotationZ & r) {
+  return *this = r * (*this); }
+
+inline HepRotation HepRotation::inverse() const {
+  return HepRotation( rxx, ryx, rzx, 
+		      rxy, ryy, rzy, 
+		      rxz, ryz, rzz );
+}
+
+inline HepRotation inverseOf (const HepRotation & r) {
+  return r.inverse();
+}
+
+inline HepRotation & HepRotation::invert() {
+  return *this=inverse();
+}
+
+inline HepRotation & HepRotation::rotate
+				(double delta, const Hep3Vector * p) {
+  return rotate(delta, *p);
+}
+
+inline bool HepRotation::operator== ( const HepRotation & r ) const {
+  return ( rxx==r.rxx && rxy==r.rxy && rxz==r.rxz &&
+	   ryx==r.ryx && ryy==r.ryy && ryz==r.ryz &&
+	   rzx==r.rzx && rzy==r.rzy && rzz==r.rzz );
+}
+inline bool HepRotation::operator!= ( const HepRotation & r ) const {
+  return ! operator==(r);
+}
+inline bool HepRotation::operator< ( const HepRotation & r ) const 
+	{ return compare(r)< 0; }
+inline bool HepRotation::operator<=( const HepRotation & r ) const 
+	{ return compare(r)<=0; }
+inline bool HepRotation::operator>=( const HepRotation & r ) const 
+	{ return compare(r)>=0; }
+inline bool HepRotation::operator> ( const HepRotation & r ) const 
+	{ return compare(r)> 0; }
+
+inline double HepRotation::getTolerance() { 
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepRotation::setTolerance(double tol) { 
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+inline HepRotation operator * (const HepRotationX & rx, const HepRotation & r){
+  HepRep3x3 m = r.rep3x3();
+  double c = rx.yy();
+  double s = rx.zy();
+  return HepRotation (        m.xx_,           m.xy_,          m.xz_,
+                        c*m.yx_-s*m.zx_, c*m.yy_-s*m.zy_, c*m.yz_-s*m.zz_,
+                        s*m.yx_+c*m.zx_, s*m.yy_+c*m.zy_, s*m.yz_+c*m.zz_ );
+}
+
+inline HepRotation operator * (const HepRotationY & ry, const HepRotation & r){
+  HepRep3x3 m = r.rep3x3();
+  double c = ry.xx();
+  double s = ry.xz();
+  return HepRotation (  c*m.xx_+s*m.zx_, c*m.xy_+s*m.zy_, c*m.xz_+s*m.zz_,
+                              m.yx_,           m.yy_,          m.yz_,
+                       -s*m.xx_+c*m.zx_,-s*m.xy_+c*m.zy_,-s*m.xz_+c*m.zz_ );
+}
+
+inline HepRotation operator * (const HepRotationZ & rz, const HepRotation & r){
+  HepRep3x3 m = r.rep3x3();
+  double c = rz.xx();
+  double s = rz.yx();
+  return HepRotation (  c*m.xx_-s*m.yx_, c*m.xy_-s*m.yy_, c*m.xz_-s*m.yz_,
+                        s*m.xx_+c*m.yx_, s*m.xy_+c*m.yy_, s*m.xz_+c*m.yz_,
+                              m.zx_,           m.zy_,          m.zz_       );
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/RotationInterfaces.h
===================================================================
--- trunk/CLHEP/Vector/RotationInterfaces.h	(revision 4)
+++ trunk/CLHEP/Vector/RotationInterfaces.h	(revision 4)
@@ -0,0 +1,411 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+
+#ifndef HEP_ROTATION_INTERFACES_H
+#define HEP_ROTATION_INTERFACES_H
+
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This contains the definition of two abstract interface classes:
+// Hep4RotationInterface 
+// Hep3RotationInterface.  
+// However, these are mostly for defining methods which should be present in
+// any 4- or 3-rotation class, however specialized.  The actual classes do
+// not inherit from these.  The virtual function overhead turns out 
+// to be too steep for that to be practical.
+//
+// It may be desirable in the future to turn these classes into constraints
+// in the Stroustrup sense, so as to enforce this interface, still without 
+// inheritance.  However, they do contain an important static:
+// static double tolerance to set criteria for relative nearness.
+//
+// This file also defines structs 
+// HepRep3x3;
+// HepRep4x4;
+// HepRep4x4Symmetric;
+// which are used by various Rotation classes.
+// 
+// Hep4RotationInterface 
+//	contains all the methods to get attributes of either a
+// 	HepLorentzRotation or a HepRotation -- any information 
+//	that pertains to a LorentzRotation can also be defined
+//	for a HepRotation.(For example, the 4x4 representation
+//	would just have 0's in the space-time entries and 1 in
+//	the time-time entry.) 
+//
+// Hep3RotationInterface 
+//	inherits from Hep4RotationInterface,  and adds methods
+//	which are well-defined only in the case of a Rotation.
+//	For example, a 3x3 representation is an attribute only
+//	if the generic LorentzRotation involves no boost.
+//
+// In terms of classes in the ZOOM PhysicsVectors package, 
+//	Hep4RotationInterface <--> LorentzTransformationInterface
+//	Hep3RotationInterface <--> RotationInterface
+//
+// Hep4RotationInterface defines the required methods for:
+//	HepLorentzRotation
+//	HepBoost
+//	HepBoostX
+//	HepBoostY
+//	HepBoostZ
+//
+// Hep3RotationInterface defines the required methods for:
+//	HepRotation
+//	HepRotationX
+//	HepRotationY
+//	HepRotationZ
+//
+// .SS See Also
+// Rotation.h, LorentzRotation.h
+//
+// .SS Author
+// Mark Fischler
+//
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/AxisAngle.h"
+
+namespace CLHEP {
+
+struct HepRep3x3;
+struct HepRep4x4;
+struct HepRep4x4Symmetric;
+
+class HepRotation;
+class HepRotationX;
+class HepRotationY;
+class HepRotationZ;
+class HepLorentzRotation;
+class HepBoost;
+class HepBoostX;
+class HepBoostY;
+class HepBoostZ;
+
+
+
+//-******************************
+//
+// Hep4RotationInterface 
+//
+//-******************************
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class Hep4RotationInterface  {
+
+  // All attributes of shared by HepLorentzRotation, HepBoost, 
+  // HepBoostX, HepBoostY, HepBoostZ.  HepRotation, HepRotationX, 
+  // HepRotationY, HepRotationZ also share this attribute interface.
+
+  friend class  HepRotation;
+  friend class  HepRotationX;
+  friend class  HepRotationY;
+  friend class  HepRotationZ;
+  friend class  HepLorentzRotation;
+  friend class  HepBoost;
+  friend class  HepBoostX;
+  friend class  HepBoostY;
+  friend class  HepBoostZ;
+
+public:
+
+  static double tolerance;        // to determine relative nearness
+
+  // ----------  Accessors:
+
+#ifdef ONLY_IN_CONCRETE_CLASSES
+  //  orthosymplectic 4-vectors:
+  HepLorentzVector col1() const;
+  HepLorentzVector col2() const;
+  HepLorentzVector col3() const;
+  HepLorentzVector col4() const;
+  HepLorentzVector row1() const;
+  HepLorentzVector row2() const;
+  HepLorentzVector row3() const;
+  HepLorentzVector row4() const;
+
+  //  individual elements:
+  double xx() const  ;
+  double xy() const  ;
+  double xz() const  ;
+  double xt() const  ;
+  double yx() const  ;
+  double yy() const  ;
+  double yz() const  ;
+  double yt() const  ;
+  double zx() const  ;
+  double zy() const  ;
+  double zz() const  ;
+  double zt() const  ;
+  double tx() const  ;
+  double ty() const  ;
+  double tz() const  ;
+  double tt() const  ;
+
+  //   4x4 representation:
+//HepRep4x4 rep4x4() const;	JMM  Declared here but not defined anywhere!
+
+  // ----------  Operations:
+  //   comparisons:
+
+  inline int compare( const Hep4RotationInterface & lt ) const;
+  // Dictionary-order comparisons, utilizing the decompose(b,r) method
+
+  //   decomposition:
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost)const;
+  // Decompose as T= R * B, where R is pure rotation, B is pure boost.
+
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation)const;
+  // Decompose as T= B * R, where R is pure rotation, B is pure boost.
+
+  bool operator == (const Hep4RotationInterface & r) const;
+  bool operator != (const Hep4RotationInterface & r) const;
+
+  //   relative comparison:
+
+  double norm2() const  ;
+  double  distance2( const Hep4RotationInterface & lt ) const  ;
+  double  howNear( const Hep4RotationInterface & lt ) const  ;
+  bool isNear (const Hep4RotationInterface & lt, 
+				   double epsilon=tolerance) const  ;
+
+  void rectify()  ;
+  // non-const but logically const correction for accumulated roundoff errors
+
+  // ----------  Apply LorentzTransformations:
+
+  HepLorentzVector operator* ( const HepLorentzVector & w ) const  ;
+  HepLorentzVector operator()( const HepLorentzVector & w ) const  ;
+  // Apply to a 4-vector
+
+  // ----------  I/O:
+
+  std::ostream & print( std::ostream & os ) const;
+
+#endif /* ONLY_IN_CONCRETE_CLASSES */
+
+  static double getTolerance();
+  static double setTolerance( double tol );
+
+  enum { ToleranceTicks = 100 };
+
+protected:
+
+  ~Hep4RotationInterface() {}	// protect destructor to forbid instatiation
+
+};  // Hep4RotationInterface
+
+
+
+
+//-******************************
+//
+// Hep3RotationInterface 
+//
+//-******************************
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class Hep3RotationInterface : public Hep4RotationInterface {
+
+  // All attributes of HepRotation, HepRotationX, HepRotationY, HepRotationZ
+  // beyond those available by virtue of being a Hep3RotationInterface.
+
+  friend class  HepRotation;
+  friend class  HepRotationX;
+  friend class  HepRotationY;
+  friend class  HepRotationZ;
+
+public:
+
+#ifdef ONLY_IN_CONCRETE_CLASSES
+
+  //   Euler angles:
+  double getPhi  () const  ;
+  double getTheta() const  ;
+  double getPsi  () const  ;
+  double    phi  () const  ;
+  double    theta() const  ;
+  double    psi  () const  ;
+  HepEulerAngles eulerAngles() const  ;
+
+  //   axis & angle of rotation:
+  double  getDelta() const  ;
+  Hep3Vector getAxis () const  ;
+  double     delta() const  ;
+  Hep3Vector    axis () const  ;
+  HepAxisAngle axisAngle() const  ;
+
+  //   orthogonal unit-length vectors:
+  Hep3Vector rowX() const;
+  Hep3Vector rowY() const;
+  Hep3Vector rowZ() const;
+
+  Hep3Vector colX() const;
+  Hep3Vector colY() const;
+  Hep3Vector colZ() const;
+
+//HepRep3x3 rep3x3() const;	JMM  Declared here but not defined anywhere!
+  //   3x3 representation
+
+  //  orthosymplectic 4-vectors treating this as a 4-rotation:
+  HepLorentzVector col1() const;
+  HepLorentzVector col2() const;
+  HepLorentzVector col3() const;
+  HepLorentzVector col4() const;
+  HepLorentzVector row1() const;
+  HepLorentzVector row2() const;
+  HepLorentzVector row3() const;
+  HepLorentzVector row4() const;
+
+  //  individual elements treating this as a 4-rotation:
+  double xt() const; 
+  double yt() const; 
+  double zt() const; 
+  double tx() const; 
+  double ty() const;
+  double tz() const;
+  double tt() const;
+
+  // ---------- Operations in the Rotation group
+
+  HepRotation operator * ( const Hep3RotationInterface & r ) const  ;
+
+  // ---------- Application
+
+  HepLorentzVector operator* ( const HepLorentzVector & w ) const  ;
+  HepLorentzVector operator()( const HepLorentzVector & w ) const  ;
+  //   apply to HepLorentzVector
+
+  Hep3Vector operator* ( const Hep3Vector & v ) const  ;
+  Hep3Vector operator()( const Hep3Vector & v ) const  ;
+  //   apply to Hep3Vector
+
+  // ---------- I/O and a helper method
+
+  std::ostream & print( std::ostream & os ) const;
+
+#endif /* ONLY_IN_CONCRETE_CLASSES */
+
+private:
+
+  ~Hep3RotationInterface() {}	// private destructor to forbid instatiation
+
+};  // Hep3RotationInterface
+
+
+
+//-***************************
+// 3x3 and 4x4 representations
+//-***************************
+
+struct HepRep3x3 {
+
+  // -----  Constructors:
+
+  inline HepRep3x3();
+
+  inline HepRep3x3(  double xx, double xy, double xz
+                   , double yx, double yy, double yz
+                   , double zx, double zy, double zz
+                   );
+
+  inline HepRep3x3( const double * array );
+  // construct from an array of doubles, holding the rotation matrix
+  // in ROW order (xx, xy, ...)
+
+  inline void setToIdentity();
+
+  // -----  The data members are public:
+  double xx_, xy_, xz_,
+            yx_, yy_, yz_,
+            zx_, zy_, zz_;
+
+  inline void getArray ( double * array ) const;
+  // fill array with the NINE doubles xx, xy, xz ... zz
+
+};  // HepRep3x3
+
+struct HepRep4x4 {
+
+  // -----  Constructors:
+  inline HepRep4x4();
+
+  inline HepRep4x4(  double xx, double xy, double xz, double xt
+                   , double yx, double yy, double yz, double yt
+                   , double zx, double zy, double zz, double zt
+                   , double tx, double ty, double tz, double tt
+                   );
+
+  inline HepRep4x4( const HepRep4x4Symmetric & rep );
+
+  inline HepRep4x4( const double * array );
+  // construct from an array of doubles, holding the transformation matrix
+  // in ROW order xx, xy, ...
+
+  inline void setToIdentity();
+
+  // -----  The data members are public:
+  double xx_, xy_, xz_, xt_,
+            yx_, yy_, yz_, yt_,
+            zx_, zy_, zz_, zt_,
+            tx_, ty_, tz_, tt_;
+                         
+  inline void getArray ( double * array ) const;
+  // fill array with the SIXTEEN doubles xx, xy, xz ... tz, tt
+
+  inline bool operator==(HepRep4x4 const & r) const;
+  inline bool operator!=(HepRep4x4 const & r) const;
+
+
+};  // HepRep4x4
+
+struct HepRep4x4Symmetric {
+
+  // -----  Constructors:
+
+  inline HepRep4x4Symmetric();
+
+  inline HepRep4x4Symmetric
+	( double xx, double xy, double xz, double xt
+                      , double yy, double yz, double yt
+                                    , double zz, double zt
+                                                  , double tt );
+
+  inline HepRep4x4Symmetric( const double * array );
+  // construct from an array of doubles, holding the transformation matrix
+  // elements in this order:  xx, xy, xz, xt, yy, yz, yt, zz, zt, tt
+
+  inline void setToIdentity();
+
+  // -----  The data members are public:
+  double xx_, xy_, xz_, xt_,
+                 yy_, yz_, yt_,
+                      zz_, zt_,
+                           tt_;
+
+  inline void getArray ( double * array ) const;
+  // fill array with the TEN doubles xx, xy, xz, xt, yy, yz, yt, zz, zt, tt
+
+};
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/RotationInterfaces.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif // ROTATION_INTERFACES_H
Index: trunk/CLHEP/Vector/RotationInterfaces.icc
===================================================================
--- trunk/CLHEP/Vector/RotationInterfaces.icc	(revision 4)
+++ trunk/CLHEP/Vector/RotationInterfaces.icc	(revision 4)
@@ -0,0 +1,153 @@
+// -*- C++ -*-
+// $Id: RotationInterfaces.icc,v 1.1 2008-06-04 14:14:59 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This contains the definitions of the inline member functions of the
+// Hep4RotationInterface and Hep3RotationInterface classes, and of the 
+// HepRep3x3 and HepRep4x4 structs.
+//
+
+namespace CLHEP {
+
+//-*********
+// HepRep3x3 
+//-*********
+
+inline HepRep3x3::HepRep3x3() : 
+	  xx_(1.0), xy_(0.0), xz_(0.0)
+	, yx_(0.0), yy_(1.0), yz_(0.0)
+	, zx_(0.0), zy_(0.0), zz_(1.0)
+{}
+
+inline HepRep3x3::HepRep3x3(  double xx, double xy, double xz
+                   , double yx, double yy, double yz
+                   , double zx, double zy, double zz
+                   ) :
+	  xx_(xx), xy_(xy), xz_(xz)
+	, yx_(yx), yy_(yy), yz_(yz)
+	, zx_(zx), zy_(zy), zz_(zz)
+{}
+
+inline HepRep3x3::HepRep3x3( const double * array ) {
+  const double * a = array; 
+  double * r = &xx_;
+  for ( int i = 0; i < 9; i++ ) { *r++ = *a++; }
+}
+
+inline void HepRep3x3::setToIdentity() {
+	  xx_ = 1.0; xy_ = 0.0; xz_ = 0.0;
+	  yx_ = 0.0; yy_ = 1.0; yz_ = 0.0;
+	  zx_ = 0.0; zy_ = 0.0; zz_ = 1.0;
+}
+
+inline void HepRep3x3::getArray( double * array ) const {
+  double * a = array; 
+  const double * r = &xx_;
+  for ( int i = 0; i < 9; i++ ) { *a++ = *r++; }
+}
+
+ 
+//-*********
+// HepRep4x4 
+//-*********
+
+inline HepRep4x4::HepRep4x4() :
+	  xx_(1.0), xy_(0.0), xz_(0.0), xt_(0.0)
+	, yx_(0.0), yy_(1.0), yz_(0.0), yt_(0.0)
+	, zx_(0.0), zy_(0.0), zz_(1.0), zt_(0.0)
+	, tx_(0.0), ty_(0.0), tz_(0.0), tt_(1.0)
+{}
+
+inline HepRep4x4::HepRep4x4(  
+		     double xx, double xy, double xz, double xt
+                   , double yx, double yy, double yz, double yt
+                   , double zx, double zy, double zz, double zt
+                   , double tx, double ty, double tz, double tt
+                   ) :
+	  xx_(xx), xy_(xy), xz_(xz), xt_(xt)
+	, yx_(yx), yy_(yy), yz_(yz), yt_(yt)
+	, zx_(zx), zy_(zy), zz_(zz), zt_(zt)
+	, tx_(tx), ty_(ty), tz_(tz), tt_(tt)
+{}
+
+inline HepRep4x4::HepRep4x4( const HepRep4x4Symmetric & rep ) :
+	  xx_(rep.xx_), xy_(rep.xy_), xz_(rep.xz_), xt_(rep.xt_)
+	, yx_(rep.xy_), yy_(rep.yy_), yz_(rep.yz_), yt_(rep.yt_)
+	, zx_(rep.xz_), zy_(rep.yz_), zz_(rep.zz_), zt_(rep.zt_)
+	, tx_(rep.xt_), ty_(rep.yt_), tz_(rep.zt_), tt_(rep.tt_)
+{}
+
+inline HepRep4x4::HepRep4x4( const double * array ) {
+  const double * a = array; 
+  double * r = &xx_;
+  for ( int i = 0; i < 16; i++ ) { *r++ = *a++; }
+}
+
+inline void HepRep4x4::setToIdentity() {
+	  xx_ = 1.0; xy_ = 0.0; xz_ = 0.0; xt_ = 0.0;
+	  yx_ = 0.0; yy_ = 1.0; yz_ = 0.0; yt_ = 0.0;
+	  zx_ = 0.0; zy_ = 0.0; zz_ = 1.0; zt_ = 0.0;
+	  tx_ = 0.0; ty_ = 0.0; tz_ = 0.0; tt_ = 1.0;
+}
+
+inline void HepRep4x4::getArray( double * array ) const {
+  double * a = array; 
+  const double * r = &xx_;
+  for ( int i = 0; i < 16; i++ ) { *a++ = *r++; }
+}
+
+inline bool HepRep4x4::operator == (const HepRep4x4 & r) const {
+  return( xx_ == r.xx_ && xy_ == r.xy_ && xz_ == r.xz_ && xt_ == r.xt_ &&
+          yx_ == r.yx_ && yy_ == r.yy_ && yz_ == r.yz_ && yt_ == r.yt_ &&
+          zx_ == r.zx_ && zy_ == r.zy_ && zz_ == r.zz_ && zt_ == r.zt_ &&
+          tx_ == r.tx_ && ty_ == r.ty_ && tz_ == r.tz_ && tt_ == r.tt_ );
+}
+
+inline bool HepRep4x4::operator != (const HepRep4x4 & r) const {
+  return !(operator== (r));
+}
+
+//-******************
+// HepRep4x4Symmetric
+//-******************
+
+inline HepRep4x4Symmetric::HepRep4x4Symmetric() :
+	  xx_(1.0), xy_(0.0), xz_(0.0), xt_(0.0)
+	,           yy_(1.0), yz_(0.0), yt_(0.0)
+	,                     zz_(1.0), zt_(0.0)
+	,                               tt_(1.0)
+{}
+
+inline HepRep4x4Symmetric::HepRep4x4Symmetric 
+        ( double xx, double xy, double xz, double xt
+                      , double yy, double yz, double yt
+                                    , double zz, double zt
+                                                  , double tt ) :
+	  xx_(xx), xy_(xy), xz_(xz), xt_(xt)
+		 , yy_(yy), yz_(yz), yt_(yt)
+			  , zz_(zz), zt_(zt)
+				   , tt_(tt)
+{}
+
+inline HepRep4x4Symmetric::HepRep4x4Symmetric( const double * array ) {
+  const double * a = array; 
+  double * r = &xx_;
+  for ( int i = 0; i < 10; i++ ) { *r++ = *a++; }
+}
+
+inline void HepRep4x4Symmetric::setToIdentity() {
+	  xx_ = 1.0; xy_ = 0.0; xz_ = 0.0; xt_ = 0.0;
+	             yy_ = 1.0; yz_ = 0.0; yt_ = 0.0;
+	                        zz_ = 1.0; zt_ = 0.0;
+	                                   tt_ = 1.0;
+}
+
+inline void HepRep4x4Symmetric::getArray( double * array ) const {
+  double * a = array; 
+  const double * r = &xx_;
+  for ( int i = 0; i < 10; i++ ) { *a++ = *r++; }
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/RotationX.h
===================================================================
--- trunk/CLHEP/Vector/RotationX.h	(revision 4)
+++ trunk/CLHEP/Vector/RotationX.h	(revision 4)
@@ -0,0 +1,290 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepRotationX class for performing rotations
+// around the X axis on objects of the Hep3Vector (and HepLorentzVector) class.
+//
+// HepRotationX is a concrete implementation of Hep3RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// ThreeVector.h, LorentzVector.h, LorentzRotation.h
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_ROTATIONX_H
+#define HEP_ROTATIONX_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+
+namespace CLHEP  {
+
+class HepRotationX;
+
+class HepRotation;
+class HepBoost;
+
+inline HepRotationX inverseOf(const HepRotationX & r);
+// Returns the inverse of a RotationX.
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepRotationX {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepRotationX();
+  // Default constructor. Gives an identity rotation. 
+
+  HepRotationX(double delta);
+  // supply angle of rotation 
+
+  inline HepRotationX(const HepRotationX & orig);
+  // Copy constructor.
+
+  inline HepRotationX & operator = (const HepRotationX & r);
+  // Assignment from a Rotation, which must be RotationX
+
+  HepRotationX & set ( double delta );
+  // set angle of rotation 
+
+  inline ~HepRotationX();
+  // Trivial destructor.
+
+  // ----------  Accessors:
+
+  inline Hep3Vector colX() const;
+  inline Hep3Vector colY() const;
+  inline Hep3Vector colZ() const;
+  // orthogonal unit-length column vectors
+
+  inline Hep3Vector rowX() const;
+  inline Hep3Vector rowY() const;
+  inline Hep3Vector rowZ() const;
+  // orthogonal unit-length row vectors
+                                
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  // Elements of the rotation matrix (Geant4).
+
+  inline HepRep3x3 rep3x3() const;
+  //   3x3 representation:
+
+  // ------------  Euler angles:
+  inline  double getPhi  () const;
+  inline  double getTheta() const;
+  inline  double getPsi  () const;
+  double    phi  () const;
+  double    theta() const;
+  double    psi  () const;
+  HepEulerAngles eulerAngles() const;
+
+  // ------------  axis & angle of rotation:
+  inline  double  getDelta() const;
+  inline  Hep3Vector getAxis () const;
+  inline  double     delta() const;
+  inline  Hep3Vector    axis () const;
+  inline  HepAxisAngle  axisAngle() const;
+  inline  void getAngleAxis(double & delta, Hep3Vector & axis) const;
+  // Returns the rotation angle and rotation axis (Geant4). 	
+
+  // ------------- Angles of rotated axes
+  double phiX() const;
+  double phiY() const;
+  double phiZ() const;
+  double thetaX() const;
+  double thetaY() const;
+  double thetaZ() const;
+  // Return angles (RADS) made by rotated axes against original axes (Geant4).
+
+  // ----------  Other accessors treating pure rotation as a 4-rotation
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  //  orthosymplectic 4-vector columns - T component will be zero
+
+  inline HepLorentzVector col4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  //  orthosymplectic 4-vector rows - T component will be zero
+
+  inline HepLorentzVector row4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline double xt() const;
+  inline double yt() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  // Will be zero for this pure Rotation
+
+  inline double tt() const;
+  // Will be one for this pure Rotation
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation.
+
+  // ---------   Mutators 
+
+  void setDelta (double delta);
+  // change angle of rotation, leaving rotation axis unchanged.
+
+  // ----------  Decomposition:
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  void decompose (HepRotation & rotation, HepBoost & boost) const;
+  void decompose (HepBoost & boost, HepRotation & rotation) const;
+  // These are trivial, as the boost vector is 0.		
+
+  // ----------  Comparisons: 
+  
+  inline bool isIdentity() const;				
+  // Returns true if the identity matrix (Geant4).	
+
+  inline int compare( const HepRotationX & r  ) const;
+  // Dictionary-order comparison, in order of delta
+  // Used in operator<, >, <=, >= 
+
+  inline bool operator== ( const HepRotationX & r ) const;
+  inline bool operator!= ( const HepRotationX & r ) const;
+  inline bool operator<  ( const HepRotationX & r ) const;
+  inline bool operator>  ( const HepRotationX & r ) const;
+  inline bool operator<= ( const HepRotationX & r ) const;
+  inline bool operator>= ( const HepRotationX & r ) const;
+  
+  double distance2( const HepRotationX & r  ) const; 
+  // 3 - Tr ( this/r )
+
+  double distance2( const HepRotation &  r  ) const; 
+  // 3 - Tr ( this/r ) -- This works with RotationY or Z also
+
+  double howNear( const HepRotationX & r ) const;
+  double howNear( const HepRotation  & r ) const;
+  bool isNear( const HepRotationX & r,
+               double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepRotation  & r,
+               double epsilon=Hep4RotationInterface::tolerance) const;
+
+  double distance2( const HepBoost           & lt  ) const; 
+  // 3 - Tr ( this ) + |b|^2 / (1-|b|^2) 
+  double distance2( const HepLorentzRotation & lt  ) const; 
+  // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt
+
+  double howNear( const HepBoost           & lt ) const;
+  double howNear( const HepLorentzRotation & lt ) const;
+  bool isNear( const HepBoost           & lt, 
+               double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepLorentzRotation & lt,
+               double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const; 
+  // distance2 (IDENTITY), which is 3 - Tr ( *this )
+
+  inline void rectify();
+  // non-const but logically moot correction for accumulated roundoff errors
+
+  // ---------- Application:
+
+  inline Hep3Vector operator() (const Hep3Vector & p) const;
+  // Rotate a Hep3Vector.					
+
+  inline  Hep3Vector operator * (const Hep3Vector & p) const;
+  // Multiplication with a Hep3Vector.
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Rotate (the space part of) a HepLorentzVector.		
+
+  inline  HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a HepLorentzVector.
+
+  // ---------- Operations in the group of Rotations 
+
+  inline HepRotationX operator * (const HepRotationX & rx) const;
+  // Product of two X rotations: (this) * rx is known to be RotationX.
+
+  inline  HepRotationX & operator *= (const HepRotationX & r);
+  inline  HepRotationX & transform   (const HepRotationX & r);
+  // Matrix multiplication.
+  // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
+  // However, in this special case, they commute:  Both just add deltas.
+
+  inline HepRotationX inverse() const;
+  // Returns the inverse.
+
+  friend HepRotationX inverseOf(const HepRotationX & r);
+  // Returns the inverse of a RotationX.
+
+  inline HepRotationX & invert();
+  // Inverts the Rotation matrix (be negating delta).
+
+  // ---------- I/O: 
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output, identifying type of rotation and delta.
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  double d;
+  // The angle of rotation.
+
+  double s;
+  double c;
+  // Cache the trig functions, for rapid operations.
+
+  inline HepRotationX ( double dd, double ss, double cc );
+  // Unchecked load-the-data-members
+
+  static inline double proper (double delta);
+  // Put an angle into the range of (-PI, PI].  Useful helper method.
+
+};  // HepRotationX
+// ---------- Free-function operations in the group of Rotations
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepRotationX & r ) {return r.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/RotationX.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_ROTATIONX_H */
Index: trunk/CLHEP/Vector/RotationX.icc
===================================================================
--- trunk/CLHEP/Vector/RotationX.icc	(revision 4)
+++ trunk/CLHEP/Vector/RotationX.icc	(revision 4)
@@ -0,0 +1,208 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepRotationX class
+//
+
+#include <cmath>
+#include "CLHEP/Units/PhysicalConstants.h"
+
+namespace CLHEP {
+
+inline double HepRotationX::yy() const { return c; }
+inline double HepRotationX::yz() const { return -s; }
+inline double HepRotationX::zy() const { return s; }
+inline double HepRotationX::zz() const { return c; }
+
+inline double HepRotationX::xx() const { return 1.0; }
+inline double HepRotationX::xy() const { return 0.0; }
+inline double HepRotationX::xz() const { return 0.0; }
+inline double HepRotationX::yx() const { return 0.0; }
+inline double HepRotationX::zx() const { return 0.0; }
+
+inline HepRep3x3 HepRotationX::rep3x3() const {
+  return HepRep3x3 ( 1.0, 0.0, 0.0,
+                     0.0,  c,   -s,
+                     0.0,  s,   c  );
+}
+
+inline HepRotationX::HepRotationX() : d(0.0), s(0.0), c(1.0) {}
+
+inline HepRotationX::HepRotationX(const HepRotationX & orig) : 
+	d(orig.d), s(orig.s), c(orig.c)
+{}
+
+inline HepRotationX::HepRotationX(double dd, double ss, double cc) :
+	d(dd), s(ss), c(cc)
+{}
+
+inline HepRotationX & HepRotationX::operator= (const HepRotationX & orig) {
+  d = orig.d;
+  s = orig.s; 
+  c = orig.c;
+  return *this;
+}
+
+inline HepRotationX::~HepRotationX() {}
+
+inline Hep3Vector HepRotationX::colX() const 
+				{ return Hep3Vector ( 1.0, 0.0, 0.0 ); }
+inline Hep3Vector HepRotationX::colY() const 
+				{ return Hep3Vector ( 0.0,  c,  s ); }
+inline Hep3Vector HepRotationX::colZ() const 
+				{ return Hep3Vector ( 0.0, -s,  c ); }
+ 
+inline Hep3Vector HepRotationX::rowX() const 
+				{ return Hep3Vector ( 1.0, 0.0, 0.0 ); }
+inline Hep3Vector HepRotationX::rowY() const 
+				{ return Hep3Vector ( 0.0,  c, -s ); }
+inline Hep3Vector HepRotationX::rowZ() const 
+				{ return Hep3Vector ( 0.0,  s,  c ); }
+
+inline double  HepRotationX::getPhi  () const { return phi();   }
+inline double  HepRotationX::getTheta() const { return theta(); }
+inline double  HepRotationX::getPsi  () const { return psi();   }
+inline double  HepRotationX::getDelta() const { return d; }
+inline Hep3Vector HepRotationX::getAxis () const { return axis();  }
+
+inline double  HepRotationX::delta() const { return d; }
+inline Hep3Vector HepRotationX::axis() const { return Hep3Vector(1,0,0); }
+
+inline HepAxisAngle HepRotationX::axisAngle() const {
+  return HepAxisAngle ( axis(), delta() );
+}
+
+inline void HepRotationX::getAngleAxis
+			(double & delta, Hep3Vector & axis) const {
+  delta = d;
+  axis  = getAxis();
+}
+
+inline HepLorentzVector HepRotationX::col1() const 
+				{ return HepLorentzVector (colX(), 0); }
+inline HepLorentzVector HepRotationX::col2() const
+				{ return HepLorentzVector (colY(), 0); }
+inline HepLorentzVector HepRotationX::col3() const
+				{ return HepLorentzVector (colZ(), 0); }
+inline HepLorentzVector HepRotationX::col4() const
+				{ return HepLorentzVector (0,0,0,1); }
+inline HepLorentzVector HepRotationX::row1() const
+				{ return HepLorentzVector (rowX(), 0); }
+inline HepLorentzVector HepRotationX::row2() const
+				{ return HepLorentzVector (rowY(), 0); }
+inline HepLorentzVector HepRotationX::row3() const
+				{ return HepLorentzVector (rowZ(), 0); }
+inline HepLorentzVector HepRotationX::row4() const
+				{ return HepLorentzVector (0,0,0,1); }
+inline double HepRotationX::xt() const { return 0.0; }
+inline double HepRotationX::yt() const { return 0.0; }
+inline double HepRotationX::zt() const { return 0.0; }
+inline double HepRotationX::tx() const { return 0.0; }
+inline double HepRotationX::ty() const { return 0.0; }
+inline double HepRotationX::tz() const { return 0.0; }
+inline double HepRotationX::tt() const { return 1.0; }
+
+inline HepRep4x4 HepRotationX::rep4x4() const {
+  return HepRep4x4 ( 1.0, 0.0, 0.0, 0.0,
+                     0.0,  c,   -s, 0.0,
+                     0.0,  s,    c, 0.0,
+                     0.0, 0.0, 0.0, 1.0 );
+}
+
+inline bool HepRotationX::isIdentity() const {
+  return ( d==0 );
+}
+
+inline int HepRotationX::compare ( const HepRotationX & r  ) const {
+  if (d > r.d) return 1; else if (d < r.d) return -1; else return 0;
+}
+
+inline bool HepRotationX::operator==(const HepRotationX & r)  const
+  { return (d==r.d); }
+inline bool HepRotationX::operator!=(const HepRotationX & r)  const
+  { return (d!=r.d); }
+inline bool HepRotationX::operator>=(const HepRotationX & r)  const
+  { return (d>=r.d); }
+inline bool HepRotationX::operator<=(const HepRotationX & r)  const
+  { return (d<=r.d); }
+inline bool HepRotationX::operator> (const HepRotationX & r)  const
+  { return (d> r.d); }
+inline bool HepRotationX::operator< (const HepRotationX & r)  const
+  { return (d< r.d); }
+
+inline void HepRotationX::rectify() { 
+  d = proper(d);  // Just in case!
+  s = std::sin(d);
+  c = std::cos(d);
+} 
+
+inline Hep3Vector HepRotationX::operator() (const Hep3Vector & p) const {
+  double x = p.x();
+  double y = p.y();
+  double z = p.z();
+  return  Hep3Vector(  x,
+                       y * c - z * s,
+                       z * c + y * s  );
+}
+
+inline Hep3Vector HepRotationX::operator * (const Hep3Vector & p) const {
+  return operator()(p);
+}
+
+inline HepLorentzVector HepRotationX::operator()
+			( const HepLorentzVector & w ) const {
+  return  HepLorentzVector( operator() (w.vect()) , w.t() );
+}
+
+inline HepLorentzVector HepRotationX::operator * 
+					(const HepLorentzVector & p) const {
+  return operator()(p);
+}
+
+inline HepRotationX & HepRotationX::operator *= (const HepRotationX & m) {
+  return *this = (*this) * (m);
+}
+
+inline HepRotationX & HepRotationX::transform(const HepRotationX & m) {
+  return *this = m * (*this);
+}
+
+inline double HepRotationX::proper( double delta ) {
+  // -PI < d <= PI
+  if ( std::fabs(delta) < CLHEP::pi ) {
+    return  delta;
+  } else {
+    register double x = delta / (CLHEP::twopi);
+    return  (CLHEP::twopi) * ( x + std::floor(.5-x) );
+  }
+}  // proper()
+
+inline HepRotationX HepRotationX::operator * ( const HepRotationX & rx ) const {
+  return HepRotationX ( HepRotationX::proper(d+rx.d),
+                        s*rx.c + c*rx.s,
+                        c*rx.c - s*rx.s );
+}
+
+inline HepRotationX HepRotationX::inverse() const {
+  return HepRotationX( proper(-d), -s, c ); 
+}
+
+inline HepRotationX inverseOf(const HepRotationX & r) {
+  return r.inverse();
+}
+
+inline HepRotationX & HepRotationX::invert() {
+  return *this=inverse();
+}
+
+inline double HepRotationX::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}       
+inline double HepRotationX::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/RotationY.h
===================================================================
--- trunk/CLHEP/Vector/RotationY.h	(revision 4)
+++ trunk/CLHEP/Vector/RotationY.h	(revision 4)
@@ -0,0 +1,291 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepRotationY class for performing rotations
+// around the X axis on objects of the Hep3Vector (and HepLorentzVector) class.
+//
+// HepRotationY is a concrete implementation of Hep3RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// ThreeVector.h, LorentzVector.h, LorentzRotation.h
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_ROTATIONY_H
+#define HEP_ROTATIONY_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+
+namespace CLHEP {
+
+class HepRotationY;
+class HepRotation;
+class HepBoost;
+
+inline HepRotationY inverseOf(const HepRotationY & r);
+// Returns the inverse of a RotationY.
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepRotationY {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepRotationY();
+  // Default constructor. Gives an identity rotation. 
+
+  HepRotationY(double delta);
+  // supply angle of rotation 
+
+  inline HepRotationY(const HepRotationY & orig);
+  // Copy constructor.
+
+  inline HepRotationY & operator = (const HepRotationY & r);
+  // Assignment from a Rotation, which must be RotationY
+
+  HepRotationY & set ( double delta );
+  // set angle of rotation 
+
+  inline ~HepRotationY();
+  // Trivial destructor.
+
+  // ----------  Accessors:
+
+  inline Hep3Vector colX() const;
+  inline Hep3Vector colY() const;
+  inline Hep3Vector colZ() const;
+  // orthogonal unit-length column vectors
+
+  inline Hep3Vector rowX() const;
+  inline Hep3Vector rowY() const;
+  inline Hep3Vector rowZ() const;
+  // orthogonal unit-length row vectors
+                                
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  // Elements of the rotation matrix (Geant4).
+
+  inline HepRep3x3 rep3x3() const;
+  //   3x3 representation:
+
+  // ------------  Euler angles:
+  inline  double getPhi  () const;
+  inline  double getTheta() const;
+  inline  double getPsi  () const;
+  double    phi  () const;
+  double    theta() const;
+  double    psi  () const;
+  HepEulerAngles eulerAngles() const;
+
+  // ------------  axis & angle of rotation:
+  inline  double  getDelta() const;
+  inline  Hep3Vector getAxis () const;
+  inline  double     delta() const;
+  inline  Hep3Vector    axis () const;
+  inline  HepAxisAngle  axisAngle() const;
+  inline  void getAngleAxis(double & delta, Hep3Vector & axis) const;
+  // Returns the rotation angle and rotation axis (Geant4). 	
+
+  // ------------- Angles of rotated axes
+  double phiX() const;
+  double phiY() const;
+  double phiZ() const;
+  double thetaX() const;
+  double thetaY() const;
+  double thetaZ() const;
+  // Return angles (RADS) made by rotated axes against original axes (Geant4).
+
+  // ----------  Other accessors treating pure rotation as a 4-rotation
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  //  orthosymplectic 4-vector columns - T component will be zero
+
+  inline HepLorentzVector col4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  //  orthosymplectic 4-vector rows - T component will be zero
+
+  inline HepLorentzVector row4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline double xt() const;
+  inline double yt() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  // Will be zero for this pure Rotation
+
+  inline double tt() const;
+  // Will be one for this pure Rotation
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation.
+
+  // ---------   Mutators 
+
+  void setDelta (double delta);
+  // change angle of rotation, leaving rotation axis unchanged.
+
+  // ----------  Decomposition:
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  void decompose (HepRotation & rotation, HepBoost & boost) const;
+  void decompose (HepBoost & boost, HepRotation & rotation) const;
+   // These are trivial, as the boost vector is 0.		
+
+  // ----------  Comparisons: 
+  
+  inline bool isIdentity() const;				
+  // Returns true if the identity matrix (Geant4).	
+
+  inline int compare( const HepRotationY & r  ) const;
+  // Dictionary-order comparison, in order of delta
+  // Used in operator<, >, <=, >=
+
+  inline bool operator== ( const HepRotationY & r ) const;
+  inline bool operator!= ( const HepRotationY & r ) const;
+  inline bool operator<  ( const HepRotationY & r ) const;
+  inline bool operator>  ( const HepRotationY & r ) const;
+  inline bool operator<= ( const HepRotationY & r ) const;
+  inline bool operator>= ( const HepRotationY & r ) const;
+
+  double distance2( const HepRotationY & r  ) const; 
+  // 3 - Tr ( this/r )
+
+  double distance2( const HepRotation &  r  ) const;
+  // 3 - Tr ( this/r ) -- This works with RotationY or Z also
+
+  double howNear( const HepRotationY & r ) const;
+  double howNear( const HepRotation  & r ) const;
+  bool isNear( const HepRotationY & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepRotation  & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+                                     
+  double distance2( const HepBoost           & lt  ) const;
+  // 3 - Tr ( this ) + |b|^2 / (1-|b|^2)
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt
+
+  double howNear( const HepBoost           & lt ) const;
+  double howNear( const HepLorentzRotation & lt ) const;
+  bool isNear( const HepBoost           & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const; 
+  // distance2 (IDENTITY), which is 3 - Tr ( *this )
+
+  inline void rectify();
+  // non-const but logically moot correction for accumulated roundoff errors
+
+  // ---------- Application:
+
+  inline Hep3Vector operator() (const Hep3Vector & p) const;
+  // Rotate a Hep3Vector.					
+
+  inline  Hep3Vector operator * (const Hep3Vector & p) const;
+  // Multiplication with a Hep3Vector.
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Rotate (the space part of) a HepLorentzVector.		
+
+  inline  HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a HepLorentzVector.
+
+  // ---------- Operations in the group of Rotations
+
+  inline HepRotationY operator * (const HepRotationY & ry) const;
+  // Product of two Y rotations (this) * ry is known to be RotationY.
+
+  inline  HepRotationY & operator *= (const HepRotationY & r);
+  inline  HepRotationY & transform   (const HepRotationY & r);
+  // Matrix multiplication.
+  // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
+  // However, in this special case, they commute:  Both just add deltas.
+
+  inline HepRotationY inverse() const;
+  // Returns the inverse.
+
+  friend HepRotationY inverseOf(const HepRotationY & r);
+  // Returns the inverse of a RotationY.
+
+  inline HepRotationY & invert();
+  // Inverts the Rotation matrix (be negating delta).
+
+  // ---------- I/O: 
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output, identifying type of rotation and delta.
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  double d;
+  // The angle of rotation.
+
+  double s;
+  double c;
+  // Cache the trig functions, for rapid operations.
+
+  inline HepRotationY ( double dd, double ss, double cc );
+  // Unchecked load-the-data-members
+
+  static inline double proper (double delta);
+  // Put an angle into the range of (-PI, PI].  Useful helper method.
+
+};  // HepRotationY
+
+// ---------- Free-function operations in the group of Rotations
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepRotationY & r ) {return r.print(os);}
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/RotationY.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_ROTATIONY_H */
+
Index: trunk/CLHEP/Vector/RotationY.icc
===================================================================
--- trunk/CLHEP/Vector/RotationY.icc	(revision 4)
+++ trunk/CLHEP/Vector/RotationY.icc	(revision 4)
@@ -0,0 +1,209 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepRotationY class
+//
+
+#include <cmath>
+#include "CLHEP/Units/PhysicalConstants.h"
+
+namespace CLHEP {
+
+inline double HepRotationY::xx() const { return c; }
+inline double HepRotationY::xz() const { return s; }
+inline double HepRotationY::zx() const { return -s; }
+inline double HepRotationY::zz() const { return c; }
+
+inline double HepRotationY::yy() const { return 1.0; }
+inline double HepRotationY::yx() const { return 0.0; }
+inline double HepRotationY::yz() const { return 0.0; }
+inline double HepRotationY::xy() const { return 0.0; }
+inline double HepRotationY::zy() const { return 0.0; }
+
+inline HepRep3x3 HepRotationY::rep3x3() const {
+  return HepRep3x3 (  c , 0.0,  s,
+                     0.0, 1.0, 0.0,
+                     -s , 0.0,  c  );
+}
+
+inline HepRotationY::HepRotationY() : d(0.0), s(0.0), c(1.0) {}
+
+inline HepRotationY::HepRotationY(const HepRotationY & orig) : 
+	d(orig.d), s(orig.s), c(orig.c)
+{}
+
+inline HepRotationY::HepRotationY(double dd, double ss, double cc) :
+	d(dd), s(ss), c(cc)
+{}
+
+inline HepRotationY & HepRotationY::operator= (const HepRotationY & orig) {
+  d = orig.d;
+  s = orig.s; 
+  c = orig.c;
+  return *this;
+}
+
+inline HepRotationY::~HepRotationY() {}
+
+inline Hep3Vector HepRotationY::colX() const 
+				{ return Hep3Vector (  c,  0.0, -s ); }
+inline Hep3Vector HepRotationY::colY() const 
+				{ return Hep3Vector ( 0.0, 1.0, 0.0 ); }
+inline Hep3Vector HepRotationY::colZ() const 
+				{ return Hep3Vector (  s,  0.0,  c ); }
+ 
+inline Hep3Vector HepRotationY::rowX() const 
+				{ return Hep3Vector (  c,  0.0,  s ); }
+inline Hep3Vector HepRotationY::rowY() const 
+				{ return Hep3Vector ( 0.0, 1.0, 0.0 ); }
+inline Hep3Vector HepRotationY::rowZ() const 
+				{ return Hep3Vector (  -s, 0.0,  c ); }
+
+inline double  HepRotationY::getPhi  () const { return phi();   }
+inline double  HepRotationY::getTheta() const { return theta(); }
+inline double  HepRotationY::getPsi  () const { return psi();   }
+inline double  HepRotationY::getDelta() const { return d; }
+inline Hep3Vector HepRotationY::getAxis () const { return axis();  }
+
+inline double  HepRotationY::delta() const { return d; }
+inline Hep3Vector HepRotationY::axis() const { return Hep3Vector(0,1,0); }
+
+inline HepAxisAngle HepRotationY::axisAngle() const {
+  return HepAxisAngle ( axis(), delta() );
+}
+
+inline void HepRotationY::getAngleAxis
+			(double & delta, Hep3Vector & axis) const {
+  delta = d;
+  axis  = getAxis();
+}
+
+inline bool HepRotationY::isIdentity() const {
+  return ( d==0 );
+}
+
+inline int HepRotationY::compare ( const HepRotationY & r  ) const {
+  if (d > r.d) return 1; else if (d < r.d) return -1; else return 0;
+}
+
+
+inline bool HepRotationY::operator==(const HepRotationY & r) const
+  { return (d==r.d); }
+inline bool HepRotationY::operator!=(const HepRotationY & r) const
+  { return (d!=r.d); }
+inline bool HepRotationY::operator>=(const HepRotationY & r) const
+  { return (d>=r.d); }
+inline bool HepRotationY::operator<=(const HepRotationY & r) const
+  { return (d<=r.d); }
+inline bool HepRotationY::operator> (const HepRotationY & r) const
+  { return (d> r.d); }
+inline bool HepRotationY::operator< (const HepRotationY & r) const
+  { return (d< r.d); }
+
+inline void HepRotationY::rectify() { 
+  d = proper(d);  // Just in case!
+  s = std::sin(d);
+  c = std::cos(d);
+} 
+
+inline Hep3Vector HepRotationY::operator() (const Hep3Vector & p) const {
+  double x = p.x();
+  double y = p.y();
+  double z = p.z();
+  return  Hep3Vector(  x * c + z * s, 
+                             y,
+                       z * c - x * s  );
+}
+
+inline Hep3Vector HepRotationY::operator * (const Hep3Vector & p) const {
+  return operator()(p);
+}
+
+inline HepLorentzVector HepRotationY::operator()
+			( const HepLorentzVector & w ) const {
+  return  HepLorentzVector( operator() (w.vect()) , w.t() );
+}
+
+inline HepLorentzVector HepRotationY::operator * 
+                                        (const HepLorentzVector & p) const {
+  return operator()(p);
+}
+
+inline HepRotationY & HepRotationY::operator *= (const HepRotationY & m) {
+  return *this = (*this) * (m);
+}
+
+inline HepRotationY & HepRotationY::transform(const HepRotationY & m) {
+  return *this = m * (*this);
+}
+
+inline double HepRotationY::proper( double delta ) {
+  // -PI < d <= PI
+  if ( std::fabs(delta) < CLHEP::pi ) {
+    return  delta;
+  } else {
+    register double x = delta / (CLHEP::twopi);
+    return  (CLHEP::twopi) * ( x + std::floor(.5-x) );
+  }
+}  // proper()
+
+inline HepRotationY HepRotationY::operator * ( const HepRotationY & ry ) const {
+  return HepRotationY ( HepRotationY::proper(d+ry.d),
+                        s*ry.c + c*ry.s,
+                        c*ry.c - s*ry.s );
+}
+
+inline HepRotationY HepRotationY::inverse() const {
+  return HepRotationY( proper(-d), -s, c ); 
+}
+
+inline HepRotationY inverseOf(const HepRotationY & r) {
+  return r.inverse();
+}
+
+inline HepRotationY & HepRotationY::invert() {
+  return *this=inverse();
+}
+
+inline HepLorentzVector HepRotationY::col1() const
+                                { return HepLorentzVector (colX(), 0); }
+inline HepLorentzVector HepRotationY::col2() const
+                                { return HepLorentzVector (colY(), 0); }
+inline HepLorentzVector HepRotationY::col3() const
+                                { return HepLorentzVector (colZ(), 0); }
+inline HepLorentzVector HepRotationY::col4() const
+                                { return HepLorentzVector (0,0,0,1); }
+inline HepLorentzVector HepRotationY::row1() const
+                                { return HepLorentzVector (rowX(), 0); }
+inline HepLorentzVector HepRotationY::row2() const
+                                { return HepLorentzVector (rowY(), 0); }
+inline HepLorentzVector HepRotationY::row3() const
+                                { return HepLorentzVector (rowZ(), 0); }
+inline HepLorentzVector HepRotationY::row4() const
+                                { return HepLorentzVector (0,0,0,1); }
+inline double HepRotationY::xt() const { return 0.0; }
+inline double HepRotationY::yt() const { return 0.0; }
+inline double HepRotationY::zt() const { return 0.0; }
+inline double HepRotationY::tx() const { return 0.0; }
+inline double HepRotationY::ty() const { return 0.0; }
+inline double HepRotationY::tz() const { return 0.0; }
+inline double HepRotationY::tt() const { return 1.0; }
+
+inline HepRep4x4 HepRotationY::rep4x4() const {
+  return HepRep4x4 (  c , 0.0,  s,  0.0,
+                     0.0, 1.0, 0.0, 0.0,
+                     -s , 0.0,  c,  0.0,
+                     0.0, 0.0, 0.0, 1.0 );
+}
+
+inline double HepRotationY::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepRotationY::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/RotationZ.h
===================================================================
--- trunk/CLHEP/Vector/RotationZ.h	(revision 4)
+++ trunk/CLHEP/Vector/RotationZ.h	(revision 4)
@@ -0,0 +1,293 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the definition of the HepRotationZ class for performing rotations
+// around the X axis on objects of the Hep3Vector (and HepLorentzVector) class.
+//
+// HepRotationZ is a concrete implementation of Hep3RotationInterface.
+//
+// .SS See Also
+// RotationInterfaces.h
+// ThreeVector.h, LorentzVector.h, LorentzRotation.h
+//
+// .SS Author
+// Mark Fischler
+
+#ifndef HEP_ROTATIONZ_H
+#define HEP_ROTATIONZ_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/RotationInterfaces.h"
+
+namespace CLHEP {
+
+class HepRotationZ;
+class HepRotation;
+class HepBoost;
+
+inline HepRotationZ inverseOf(const HepRotationZ & r);
+// Returns the inverse of a RotationZ.
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class HepRotationZ {
+
+public:
+
+  // ----------  Constructors and Assignment:
+
+  inline HepRotationZ();
+  // Default constructor. Gives an identity rotation. 
+
+  HepRotationZ(double delta);
+  // supply angle of rotation 
+
+  inline HepRotationZ(const HepRotationZ & orig);
+  // Copy constructor.
+
+  inline HepRotationZ & operator = (const HepRotationZ & r);
+  // Assignment from a Rotation, which must be RotationZ
+
+  HepRotationZ & set ( double delta );
+  // set angle of rotation 
+
+  inline ~HepRotationZ();
+  // Trivial destructor.
+
+  // ----------  Accessors:
+
+  inline Hep3Vector colX() const;
+  inline Hep3Vector colY() const;
+  inline Hep3Vector colZ() const;
+  // orthogonal unit-length column vectors
+
+  inline Hep3Vector rowX() const;
+  inline Hep3Vector rowY() const;
+  inline Hep3Vector rowZ() const;
+  // orthogonal unit-length row vectors
+                                
+  inline double xx() const;
+  inline double xy() const;
+  inline double xz() const;
+  inline double yx() const;
+  inline double yy() const;
+  inline double yz() const;
+  inline double zx() const;
+  inline double zy() const;
+  inline double zz() const;
+  // Elements of the rotation matrix (Geant4).
+
+  inline HepRep3x3 rep3x3() const;
+  //   3x3 representation:
+
+  // ------------  Euler angles:
+  inline  double getPhi  () const;
+  inline  double getTheta() const;
+  inline  double getPsi  () const;
+  double    phi  () const;
+  double    theta() const;
+  double    psi  () const;
+  HepEulerAngles eulerAngles() const;
+
+  // ------------  axis & angle of rotation:
+  inline  double  getDelta() const;
+  inline  Hep3Vector getAxis () const;
+  inline  double     delta() const;
+  inline  Hep3Vector    axis () const;
+  inline  HepAxisAngle  axisAngle() const;
+  inline  void getAngleAxis(double & delta, Hep3Vector & axis) const;
+  // Returns the rotation angle and rotation axis (Geant4). 	
+
+  // ------------- Angles of rotated axes
+  double phiX() const;
+  double phiY() const;
+  double phiZ() const;
+  double thetaX() const;
+  double thetaY() const;
+  double thetaZ() const;
+  // Return angles (RADS) made by rotated axes against original axes (Geant4).
+
+  // ----------  Other accessors treating pure rotation as a 4-rotation
+
+  inline HepLorentzVector col1() const;
+  inline HepLorentzVector col2() const;
+  inline HepLorentzVector col3() const;
+  //  orthosymplectic 4-vector columns - T component will be zero
+
+  inline HepLorentzVector col4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline HepLorentzVector row1() const;
+  inline HepLorentzVector row2() const;
+  inline HepLorentzVector row3() const;
+  //  orthosymplectic 4-vector rows - T component will be zero
+
+  inline HepLorentzVector row4() const;
+  // Will be (0,0,0,1) for this pure Rotation.
+
+  inline double xt() const;
+  inline double yt() const;
+  inline double zt() const;
+  inline double tx() const;
+  inline double ty() const;
+  inline double tz() const;
+  // Will be zero for this pure Rotation
+
+  inline double tt() const;
+  // Will be one for this pure Rotation
+
+  inline HepRep4x4 rep4x4() const;
+  //   4x4 representation.
+
+  // ---------   Mutators 
+
+  void setDelta (double delta);
+  // change angle of rotation, leaving rotation axis unchanged.
+
+  // ----------  Decomposition:
+
+  void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
+  void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
+  void decompose (HepRotation & rotation, HepBoost & boost) const;
+  void decompose (HepBoost & boost, HepRotation & rotation) const;
+   // These are trivial, as the boost vector is 0.		
+
+  // ----------  Comparisons: 
+  
+  inline bool isIdentity() const;				
+  // Returns true if the identity matrix (Geant4).	
+
+  inline int compare( const HepRotationZ & r  ) const;
+  // Dictionary-order comparison, in order of delta
+  // Used in operator<, >, <=, >=
+
+  inline bool operator== ( const HepRotationZ & r ) const;
+  inline bool operator!= ( const HepRotationZ & r ) const;
+  inline bool operator<  ( const HepRotationZ & r ) const;
+  inline bool operator>  ( const HepRotationZ & r ) const;
+  inline bool operator<= ( const HepRotationZ & r ) const;
+  inline bool operator>= ( const HepRotationZ & r ) const;
+
+  double distance2( const HepRotationZ & r  ) const; 
+  // 3 - Tr ( this/r )
+
+  double distance2( const HepRotation &  r  ) const;
+  // 3 - Tr ( this/r ) -- This works with RotationY or Z also
+
+  double howNear( const HepRotationZ & r ) const;
+  double howNear( const HepRotation  & r ) const;
+  bool isNear( const HepRotationZ & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepRotation  & r,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+                                     
+  double distance2( const HepBoost           & lt  ) const;
+  // 3 - Tr ( this ) + |b|^2 / (1-|b|^2)
+  double distance2( const HepLorentzRotation & lt  ) const;
+  // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt
+
+  double howNear( const HepBoost           & lt ) const;
+  double howNear( const HepLorentzRotation & lt ) const;
+  bool isNear( const HepBoost           & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+  bool isNear( const HepLorentzRotation & lt,
+             double epsilon=Hep4RotationInterface::tolerance) const;
+
+  // ----------  Properties:
+
+  double norm2() const; 
+  // distance2 (IDENTITY), which is 3 - Tr ( *this )
+
+  inline void rectify();
+  // non-const but logically moot correction for accumulated roundoff errors
+
+  // ---------- Application:
+
+  inline Hep3Vector operator() (const Hep3Vector & p) const;
+  // Rotate a Hep3Vector.					
+
+  inline  Hep3Vector operator * (const Hep3Vector & p) const;
+  // Multiplication with a Hep3Vector.
+
+  inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
+  // Rotate (the space part of) a HepLorentzVector.		
+
+  inline  HepLorentzVector operator* ( const HepLorentzVector & w ) const;
+  // Multiplication with a HepLorentzVector.
+
+ // ---------- Operations in the group of Rotations
+
+  inline HepRotationZ operator * (const HepRotationZ & rz) const;
+  // Product of two Z rotations:  (this) * rz is known to be RotationZ.
+
+  // Product of two rotations (this) * b - matrix multiplication  
+
+  inline  HepRotationZ & operator *= (const HepRotationZ & r);
+  inline  HepRotationZ & transform   (const HepRotationZ & r);
+  // Matrix multiplication.
+  // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
+  // However, in this special case, they commute:  Both just add deltas.
+
+  inline HepRotationZ inverse() const;
+  // Returns the inverse.
+
+  friend HepRotationZ inverseOf(const HepRotationZ & r);
+  // Returns the inverse of a RotationZ.
+
+  inline HepRotationZ & invert();
+  // Inverts the Rotation matrix (be negating delta).
+
+  // ---------- I/O: 
+
+  std::ostream & print( std::ostream & os ) const;
+  // Output, identifying type of rotation and delta.
+
+  // ---------- Tolerance
+
+  static inline double getTolerance();
+  static inline double setTolerance(double tol);
+
+protected:
+
+  double d;
+  // The angle of rotation.
+
+  double s;
+  double c;
+  // Cache the trig functions, for rapid operations.
+
+  inline HepRotationZ ( double dd, double ss, double cc );
+  // Unchecked load-the-data-members
+
+  static inline double proper (double delta);
+  // Put an angle into the range of (-PI, PI].  Useful helper method.
+
+};  // HepRotationZ
+
+inline   
+std::ostream & operator << 
+	( std::ostream & os, const HepRotationZ & r ) {return r.print(os);}
+
+// ---------- Free-function operations in the group of Rotations
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/RotationZ.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_ROTATIONZ_H */
+
Index: trunk/CLHEP/Vector/RotationZ.icc
===================================================================
--- trunk/CLHEP/Vector/RotationZ.icc	(revision 4)
+++ trunk/CLHEP/Vector/RotationZ.icc	(revision 4)
@@ -0,0 +1,208 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// HepRotationZ class
+//
+
+#include <cmath>
+#include "CLHEP/Units/PhysicalConstants.h"
+
+namespace CLHEP {
+
+inline double HepRotationZ::xx() const { return c; }
+inline double HepRotationZ::xy() const { return -s; }
+inline double HepRotationZ::yx() const { return s; }
+inline double HepRotationZ::yy() const { return c; }
+
+inline double HepRotationZ::zz() const { return 1.0; }
+inline double HepRotationZ::zy() const { return 0.0; }
+inline double HepRotationZ::zx() const { return 0.0; }
+inline double HepRotationZ::yz() const { return 0.0; }
+inline double HepRotationZ::xz() const { return 0.0; }
+
+inline HepRep3x3 HepRotationZ::rep3x3() const {
+  return HepRep3x3 (  c,  -s,  0.0,
+                      s,   c,  0.0,
+                     0.0, 0.0, 1.0  );
+}
+
+inline HepRotationZ::HepRotationZ() : d(0.0), s(0.0), c(1.0) {}
+
+inline HepRotationZ::HepRotationZ(const HepRotationZ & orig) : 
+	d(orig.d), s(orig.s), c(orig.c)
+{}
+
+inline HepRotationZ::HepRotationZ(double dd, double ss, double cc) :
+	d(dd), s(ss), c(cc)
+{}
+
+inline HepRotationZ & HepRotationZ::operator= (const HepRotationZ & orig) {
+  d = orig.d;
+  s = orig.s; 
+  c = orig.c;
+  return *this;
+}
+
+inline HepRotationZ::~HepRotationZ() {}
+
+inline Hep3Vector HepRotationZ::colX() const 
+				{ return Hep3Vector (  c,   s,  0.0 ); }
+inline Hep3Vector HepRotationZ::colY() const 
+				{ return Hep3Vector ( -s,   c,  0.0 ); }
+inline Hep3Vector HepRotationZ::colZ() const 
+				{ return Hep3Vector ( 0.0, 0.0, 1.0 ); }
+ 
+inline Hep3Vector HepRotationZ::rowX() const 
+				{ return Hep3Vector (  c,  -s,  0.0 ); }
+inline Hep3Vector HepRotationZ::rowY() const 
+				{ return Hep3Vector (  s,   c,  0.0 ); }
+inline Hep3Vector HepRotationZ::rowZ() const 
+				{ return Hep3Vector ( 0.0, 0.0, 1.0 ); }
+
+inline double  HepRotationZ::getPhi  () const { return phi();   }
+inline double  HepRotationZ::getTheta() const { return theta(); }
+inline double  HepRotationZ::getPsi  () const { return psi();   }
+inline double  HepRotationZ::getDelta() const { return d; }
+inline Hep3Vector HepRotationZ::getAxis () const { return axis();  }
+
+inline double  HepRotationZ::delta() const { return d; }
+inline Hep3Vector HepRotationZ::axis() const { return Hep3Vector(0,0,1); }
+
+inline HepAxisAngle HepRotationZ::axisAngle() const {
+  return HepAxisAngle ( axis(), delta() );
+}
+
+inline void HepRotationZ::getAngleAxis
+			(double & delta, Hep3Vector & axis) const {
+  delta = d;
+  axis  = getAxis();
+}
+
+inline bool HepRotationZ::isIdentity() const {
+  return ( d==0 );
+}
+
+inline int HepRotationZ::compare ( const HepRotationZ & r  ) const {
+  if (d > r.d) return 1; else if (d < r.d) return -1; else return 0;
+}
+
+inline bool HepRotationZ::operator==(const HepRotationZ & r) const
+  { return (d==r.d); }
+inline bool HepRotationZ::operator!=(const HepRotationZ & r) const
+  { return (d!=r.d); }
+inline bool HepRotationZ::operator>=(const HepRotationZ & r) const
+  { return (d>=r.d); }
+inline bool HepRotationZ::operator<=(const HepRotationZ & r) const
+  { return (d<=r.d); }
+inline bool HepRotationZ::operator> (const HepRotationZ & r) const
+  { return (d> r.d); }
+inline bool HepRotationZ::operator< (const HepRotationZ & r) const
+  { return (d< r.d); }
+
+inline void HepRotationZ::rectify() { 
+  d = proper(d);  // Just in case!
+  s = std::sin(d);
+  c = std::cos(d);
+} 
+
+inline Hep3Vector HepRotationZ::operator() (const Hep3Vector & p) const {
+  double x = p.x();
+  double y = p.y();
+  double z = p.z();
+  return  Hep3Vector(  x * c - y * s,
+                       x * s + y * c,
+                             z        );
+}
+
+inline Hep3Vector HepRotationZ::operator * (const Hep3Vector & p) const {
+  return operator()(p);
+}
+
+inline HepLorentzVector HepRotationZ::operator()
+			( const HepLorentzVector & w ) const {
+  return  HepLorentzVector( operator() (w.vect()) , w.t() );
+}
+
+inline HepLorentzVector HepRotationZ::operator * 
+                                        (const HepLorentzVector & p) const {
+  return operator()(p);
+}
+
+inline HepRotationZ & HepRotationZ::operator *= (const HepRotationZ & m) {
+  return *this = (*this) * (m);
+}
+
+inline HepRotationZ & HepRotationZ::transform(const HepRotationZ & m) {
+  return *this = m * (*this);
+}
+
+inline double HepRotationZ::proper( double delta ) {
+  // -PI < d <= PI
+  if ( std::fabs(delta) < CLHEP::pi ) {
+    return  delta;
+  } else {
+    register double x = delta / (CLHEP::twopi);
+    return  (CLHEP::twopi) * ( x + std::floor(.5-x) );
+  }
+}  // proper()
+
+inline HepRotationZ HepRotationZ::operator * ( const HepRotationZ & rz ) const {
+  return HepRotationZ ( HepRotationZ::proper(d+rz.d),
+                        s*rz.c + c*rz.s,
+                        c*rz.c - s*rz.s );
+}
+
+inline HepRotationZ HepRotationZ::inverse() const {
+  return HepRotationZ( proper(-d), -s, c ); 
+}
+
+inline HepRotationZ inverseOf(const HepRotationZ & r) {
+  return r.inverse();
+}
+
+inline HepRotationZ & HepRotationZ::invert() {
+  return *this=inverse();
+}
+
+inline HepLorentzVector HepRotationZ::col1() const
+                                { return HepLorentzVector (colX(), 0); }
+inline HepLorentzVector HepRotationZ::col2() const
+                                { return HepLorentzVector (colY(), 0); }
+inline HepLorentzVector HepRotationZ::col3() const
+                                { return HepLorentzVector (colZ(), 0); }
+inline HepLorentzVector HepRotationZ::col4() const
+                                { return HepLorentzVector (0,0,0,1); }
+inline HepLorentzVector HepRotationZ::row1() const
+                                { return HepLorentzVector (rowX(), 0); }
+inline HepLorentzVector HepRotationZ::row2() const
+                                { return HepLorentzVector (rowY(), 0); }
+inline HepLorentzVector HepRotationZ::row3() const
+                                { return HepLorentzVector (rowZ(), 0); }
+inline HepLorentzVector HepRotationZ::row4() const
+                                { return HepLorentzVector (0,0,0,1); }
+inline double HepRotationZ::xt() const { return 0.0; }
+inline double HepRotationZ::yt() const { return 0.0; }
+inline double HepRotationZ::zt() const { return 0.0; }
+inline double HepRotationZ::tx() const { return 0.0; }
+inline double HepRotationZ::ty() const { return 0.0; }
+inline double HepRotationZ::tz() const { return 0.0; }
+inline double HepRotationZ::tt() const { return 1.0; }
+
+inline HepRep4x4 HepRotationZ::rep4x4() const {
+  return HepRep4x4 (  c,  -s,  0.0, 0.0, 
+                      s,   c,  0.0, 0.0, 
+                     0.0, 0.0, 1.0, 0.0,
+                     0.0, 0.0, 0.0, 1.0 );
+}
+
+inline double HepRotationZ::getTolerance() {
+  return Hep4RotationInterface::tolerance;
+}
+inline double HepRotationZ::setTolerance(double tol) {
+  return Hep4RotationInterface::setTolerance(tol);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/Sqr.h
===================================================================
--- trunk/CLHEP/Vector/Sqr.h	(revision 4)
+++ trunk/CLHEP/Vector/Sqr.h	(revision 4)
@@ -0,0 +1,26 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// $Id: Sqr.h,v 1.1 2008-06-04 14:15:01 demin Exp $
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This file contains a template definition of sqr() 
+// sqr() is used only by Vector/test/testLorentzVector.cc
+//
+#ifndef HEP_SQR_H
+#define HEP_SQR_H
+ 
+#ifndef CLHEP_SQR_DEFINED
+#define CLHEP_SQR_DEFINED
+#ifdef sqr
+#undef sqr
+#endif
+template <class T>
+inline T sqr(const T& x) {
+  return x*x;
+}
+#endif
+ 
+#endif /* HEP_SQR_H */
Index: trunk/CLHEP/Vector/ThreeVector.h
===================================================================
--- trunk/CLHEP/Vector/ThreeVector.h	(revision 4)
+++ trunk/CLHEP/Vector/ThreeVector.h	(revision 4)
@@ -0,0 +1,453 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// $Id: ThreeVector.h,v 1.1 2008-06-04 14:15:02 demin Exp $
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// Hep3Vector is a general 3-vector class defining vectors in three
+// dimension using double components. Rotations of these vectors are
+// performed by multiplying with an object of the HepRotation class.
+//
+// .SS See Also
+// LorentzVector.h, Rotation.h, LorentzRotation.h 
+//
+// .SS Authors
+// Leif Lonnblad and Anders Nilsson; Modified by Evgueni Tcherniaev;
+// ZOOM additions by Mark Fischler
+//
+
+#ifndef HEP_THREEVECTOR_H
+#define HEP_THREEVECTOR_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include <iostream>
+#include "CLHEP/Vector/defs.h" 
+
+namespace CLHEP {
+
+class HepRotation;
+class HepEulerAngles;
+class HepAxisAngle;
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class Hep3Vector {
+
+public:
+
+// Basic properties and operations on 3-vectors:  
+
+  enum { X=0, Y=1, Z=2, NUM_COORDINATES=3, SIZE=NUM_COORDINATES };
+  // Safe indexing of the coordinates when using with matrices, arrays, etc.
+  // (BaBar)
+
+  inline Hep3Vector(double x = 0.0, double y = 0.0, double z = 0.0);
+  // The constructor.  
+
+  inline Hep3Vector(const Hep3Vector &);
+  // The copy constructor.
+
+  inline ~Hep3Vector();
+  // The destructor.  Not virtual - inheritance from this class is dangerous.
+
+  double operator () (int) const;
+  // Get components by index -- 0-based (Geant4) 
+
+  inline double operator [] (int) const;
+  // Get components by index -- 0-based (Geant4) 
+
+  double & operator () (int);
+  // Set components by index.  0-based.
+
+  inline double & operator [] (int);
+  // Set components by index.  0-based.
+
+  inline double x() const;
+  inline double y() const;
+  inline double z() const;
+  // The components in cartesian coordinate system.  Same as getX() etc.
+
+  inline void setX(double);
+  inline void setY(double);
+  inline void setZ(double);
+  // Set the components in cartesian coordinate system.
+
+  inline void set( double x, double y, double z); 
+  // Set all three components in cartesian coordinate system.
+
+  inline double phi() const;
+  // The azimuth angle.
+
+  inline double theta() const;
+  // The polar angle.
+
+  inline double cosTheta() const;
+  // Cosine of the polar angle.
+
+  inline double cos2Theta() const;
+  // Cosine squared of the polar angle - faster than cosTheta(). (ZOOM)
+
+  inline double mag2() const;
+  // The magnitude squared (r^2 in spherical coordinate system).
+
+  inline double mag() const;
+  // The magnitude (r in spherical coordinate system).
+
+  inline void setPhi(double);
+  // Set phi keeping mag and theta constant (BaBar).
+
+  inline void setTheta(double);
+  // Set theta keeping mag and phi constant (BaBar).
+
+         void setMag(double);
+  // Set magnitude keeping theta and phi constant (BaBar).
+
+  inline double perp2() const;
+  // The transverse component squared (rho^2 in cylindrical coordinate system).
+
+  inline double perp() const;
+  // The transverse component (rho in cylindrical coordinate system).
+
+  inline void setPerp(double);
+  // Set the transverse component keeping phi and z constant.
+
+  void setCylTheta(double);
+  // Set theta while keeping transvers component and phi fixed 
+
+  inline double perp2(const Hep3Vector &) const;
+  // The transverse component w.r.t. given axis squared.
+
+  inline double perp(const Hep3Vector &) const;
+  // The transverse component w.r.t. given axis.
+
+  inline Hep3Vector & operator = (const Hep3Vector &);
+  // Assignment.
+
+  inline bool operator == (const Hep3Vector &) const;
+  inline bool operator != (const Hep3Vector &) const;
+  // Comparisons (Geant4). 
+
+  bool isNear (const Hep3Vector &, double epsilon=tolerance) const;
+  // Check for equality within RELATIVE tolerance (default 2.2E-14). (ZOOM)
+  // |v1 - v2|**2 <= epsilon**2 * |v1.dot(v2)| 
+
+  double howNear(const Hep3Vector & v ) const;
+  // sqrt ( |v1-v2|**2 / v1.dot(v2) ) with a maximum of 1.
+  // If v1.dot(v2) is negative, will return 1.
+
+  double deltaR(const Hep3Vector & v) const;
+  // sqrt( pseudorapity_difference**2 + deltaPhi **2 )
+
+  inline Hep3Vector & operator += (const Hep3Vector &);
+  // Addition.
+
+  inline Hep3Vector & operator -= (const Hep3Vector &);
+  // Subtraction.
+
+  inline Hep3Vector operator - () const;
+  // Unary minus.
+
+  inline Hep3Vector & operator *= (double);
+  // Scaling with real numbers.
+
+         Hep3Vector & operator /= (double);
+  // Division by (non-zero) real number.
+
+  inline Hep3Vector unit() const;
+  // Vector parallel to this, but of length 1.
+
+  inline Hep3Vector orthogonal() const;
+  // Vector orthogonal to this (Geant4).
+
+  inline double dot(const Hep3Vector &) const;
+  // double product.
+
+  inline Hep3Vector cross(const Hep3Vector &) const;
+  // Cross product.
+
+  double angle(const Hep3Vector &) const;
+  // The angle w.r.t. another 3-vector.
+
+  double pseudoRapidity() const;
+  // Returns the pseudo-rapidity, i.e. -ln(tan(theta/2))
+
+  void setEta  ( double p );
+  // Set pseudo-rapidity, keeping magnitude and phi fixed.  (ZOOM)
+
+  void setCylEta  ( double p );
+  // Set pseudo-rapidity, keeping transverse component and phi fixed.  (ZOOM)
+
+  Hep3Vector & rotateX(double);
+  // Rotates the Hep3Vector around the x-axis.
+
+  Hep3Vector & rotateY(double);
+  // Rotates the Hep3Vector around the y-axis.
+
+  Hep3Vector & rotateZ(double);
+  // Rotates the Hep3Vector around the z-axis.
+
+  Hep3Vector & rotateUz(const Hep3Vector&);
+  // Rotates reference frame from Uz to newUz (unit vector) (Geant4).
+
+    Hep3Vector & rotate(double, const Hep3Vector &);
+  // Rotates around the axis specified by another Hep3Vector.
+  // (Uses methods of HepRotation, forcing linking in of Rotation.cc.)
+
+  Hep3Vector & operator *= (const HepRotation &);
+  Hep3Vector & transform(const HepRotation &);
+  // Transformation with a Rotation matrix.
+
+
+
+// = = = = = = = = = = = = = = = = = = = = = = = =
+//
+// Esoteric properties and operations on 3-vectors:  
+//
+// 1 - Set vectors in various coordinate systems
+// 2 - Synonyms for accessing coordinates and properties
+// 3 - Comparisions (dictionary, near-ness, and geometric)
+// 4 - Intrinsic properties 
+// 5 - Properties releative to z axis and arbitrary directions
+// 6 - Polar and azimuthal angle decomposition and deltaPhi
+// 7 - Rotations 
+//
+// = = = = = = = = = = = = = = = = = = = = = = = =
+
+// 1 - Set vectors in various coordinate systems
+
+  inline void setRThetaPhi  (double r, double theta, double phi);
+  // Set in spherical coordinates:  Angles are measured in RADIANS
+
+  inline void setREtaPhi  ( double r, double eta,  double phi );
+  // Set in spherical coordinates, but specify peudorapidiy to determine theta.
+
+  inline void setRhoPhiZ   (double rho, double phi, double z);
+  // Set in cylindrical coordinates:  Phi angle is measured in RADIANS
+
+  void setRhoPhiTheta ( double rho, double phi, double theta);
+  // Set in cylindrical coordinates, but specify theta to determine z.
+
+  void setRhoPhiEta ( double rho, double phi, double eta);
+  // Set in cylindrical coordinates, but specify pseudorapidity to determine z.
+
+// 2 - Synonyms for accessing coordinates and properties
+
+  inline double getX() const; 
+  inline double getY() const;
+  inline double getZ() const; 
+  // x(), y(), and z()
+
+  inline double getR    () const;
+  inline double getTheta() const;
+  inline double getPhi  () const;
+  // mag(), theta(), and phi()
+
+  inline double r       () const;
+  // mag()
+
+  inline double rho     () const;
+  inline double getRho  () const;
+  // perp()
+
+  double eta     () const;
+  double getEta  () const;
+  // pseudoRapidity() 
+
+  inline void setR ( double s );
+  // setMag()
+
+  inline void setRho ( double s );
+  // setPerp()
+
+// 3 - Comparisions (dictionary, near-ness, and geometric)
+
+  int compare (const Hep3Vector & v) const;
+  bool operator > (const Hep3Vector & v) const;
+  bool operator < (const Hep3Vector & v) const;
+  bool operator>= (const Hep3Vector & v) const;
+  bool operator<= (const Hep3Vector & v) const;
+  // dictionary ordering according to z, then y, then x component
+
+  inline double diff2 (const Hep3Vector & v) const;
+  // |v1-v2|**2
+
+  static double setTolerance (double tol);
+  static inline double getTolerance ();
+  // Set the tolerance used in isNear() for Hep3Vectors 
+
+  bool isParallel (const Hep3Vector & v, double epsilon=tolerance) const;
+  // Are the vectors parallel, within the given tolerance?
+
+  bool isOrthogonal (const Hep3Vector & v, double epsilon=tolerance) const;
+  // Are the vectors orthogonal, within the given tolerance?
+
+  double howParallel   (const Hep3Vector & v) const;
+  // | v1.cross(v2) / v1.dot(v2) |, to a maximum of 1.
+
+  double howOrthogonal (const Hep3Vector & v) const;
+  // | v1.dot(v2) / v1.cross(v2) |, to a maximum of 1.
+
+  enum { ToleranceTicks = 100 };
+
+// 4 - Intrinsic properties 
+
+  double beta    () const;
+  // relativistic beta (considering v as a velocity vector with c=1)
+  // Same as mag() but will object if >= 1
+
+  double gamma() const;
+  // relativistic gamma (considering v as a velocity vector with c=1)
+
+  double coLinearRapidity() const;
+  // inverse tanh (beta)
+
+// 5 - Properties relative to Z axis and to an arbitrary direction
+
+	  // Note that the non-esoteric CLHEP provides 
+	  // theta(), cosTheta(), cos2Theta, and angle(const Hep3Vector&)
+
+  inline double angle() const;
+  // angle against the Z axis -- synonym for theta()
+
+  inline double theta(const Hep3Vector & v2) const;  
+  // synonym for angle(v2)
+
+  double cosTheta (const Hep3Vector & v2) const;
+  double cos2Theta(const Hep3Vector & v2) const;
+  // cos and cos^2 of the angle between two vectors
+
+  inline Hep3Vector project () const;
+         Hep3Vector project (const Hep3Vector & v2) const;
+  // projection of a vector along a direction.  
+
+  inline Hep3Vector perpPart() const;
+  inline Hep3Vector perpPart (const Hep3Vector & v2) const;
+  // vector minus its projection along a direction.
+
+  double rapidity () const;
+  // inverse tanh(v.z())
+
+  double rapidity (const Hep3Vector & v2) const;
+  // rapidity with respect to specified direction:  
+  // inverse tanh (v.dot(u)) where u is a unit in the direction of v2
+
+  double eta(const Hep3Vector & v2) const;
+  // - ln tan of the angle beween the vector and the ref direction.
+
+// 6 - Polar and azimuthal angle decomposition and deltaPhi
+
+  // Decomposition of an angle within reference defined by a direction:
+
+  double polarAngle (const Hep3Vector & v2) const;
+  // The reference direction is Z: the polarAngle is abs(v.theta()-v2.theta()).
+
+  double deltaPhi (const Hep3Vector & v2) const;
+  // v.phi()-v2.phi(), brought into the range (-PI,PI]
+
+  double azimAngle  (const Hep3Vector & v2) const;
+  // The reference direction is Z: the azimAngle is the same as deltaPhi
+
+  double polarAngle (const Hep3Vector & v2, 
+					const Hep3Vector & ref) const;
+  // For arbitrary reference direction, 
+  // 	polarAngle is abs(v.angle(ref) - v2.angle(ref)).
+
+  double azimAngle  (const Hep3Vector & v2, 
+					const Hep3Vector & ref) const;
+  // To compute azimangle, project v and v2 into the plane normal to
+  // the reference direction.  Then in that plane take the angle going
+  // clockwise around the direction from projection of v to that of v2.
+
+// 7 - Rotations 
+
+// These mehtods **DO NOT** use anything in the HepRotation class.
+// Thus, use of v.rotate(axis,delta) does not force linking in Rotation.cc.
+
+  Hep3Vector & rotate  (const Hep3Vector & axis, double delta);
+  // Synonym for rotate (delta, axis)
+
+  Hep3Vector & rotate  (const HepAxisAngle & ax);
+  // HepAxisAngle is a struct holding an axis direction and an angle.
+
+  Hep3Vector & rotate (const HepEulerAngles & e);
+  Hep3Vector & rotate (double phi,
+                        double theta,
+                        double psi);
+  // Rotate via Euler Angles. Our Euler Angles conventions are 
+  // those of Goldstein Classical Mechanics page 107.
+
+protected:
+  void setSpherical (double r, double theta, double phi);
+  void setCylindrical (double r, double phi, double z);
+  double negativeInfinity() const;
+
+protected:
+
+  double dx;
+  double dy;
+  double dz;
+  // The components.
+
+  static double tolerance;
+  // default tolerance criterion for isNear() to return true.
+};  // Hep3Vector
+
+// Global Methods
+
+Hep3Vector rotationXOf (const Hep3Vector & vec, double delta);
+Hep3Vector rotationYOf (const Hep3Vector & vec, double delta);
+Hep3Vector rotationZOf (const Hep3Vector & vec, double delta);
+
+Hep3Vector rotationOf (const Hep3Vector & vec, 
+				const Hep3Vector & axis, double delta);
+Hep3Vector rotationOf (const Hep3Vector & vec, const HepAxisAngle & ax);
+
+Hep3Vector rotationOf (const Hep3Vector & vec, 
+				double phi, double theta, double psi);
+Hep3Vector rotationOf (const Hep3Vector & vec, const HepEulerAngles & e);
+// Return a new vector based on a rotation of the supplied vector
+
+std::ostream & operator << (std::ostream &, const Hep3Vector &);
+// Output to a stream.
+
+std::istream & operator >> (std::istream &, Hep3Vector &);
+// Input from a stream.
+
+extern const Hep3Vector HepXHat, HepYHat, HepZHat;
+
+typedef Hep3Vector HepThreeVectorD;
+typedef Hep3Vector HepThreeVectorF;
+
+Hep3Vector operator / (const Hep3Vector &, double a);
+// Division of 3-vectors by non-zero real number
+
+inline Hep3Vector operator + (const Hep3Vector &, const Hep3Vector &);
+// Addition of 3-vectors.
+
+inline Hep3Vector operator - (const Hep3Vector &, const Hep3Vector &);
+// Subtraction of 3-vectors.
+
+inline double operator * (const Hep3Vector &, const Hep3Vector &);
+// double product of 3-vectors.
+
+inline Hep3Vector operator * (const Hep3Vector &, double a);
+inline Hep3Vector operator * (double a, const Hep3Vector &);
+// Scaling of 3-vectors with a real number
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/ThreeVector.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+#endif /* HEP_THREEVECTOR_H */
Index: trunk/CLHEP/Vector/ThreeVector.icc
===================================================================
--- trunk/CLHEP/Vector/ThreeVector.icc	(revision 4)
+++ trunk/CLHEP/Vector/ThreeVector.icc	(revision 4)
@@ -0,0 +1,286 @@
+// -*- C++ -*-
+// $Id: ThreeVector.icc,v 1.1 2008-06-04 14:15:02 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// Hep3Vector class.
+//
+
+#include <cmath>
+
+namespace CLHEP {
+
+// ------------------
+// Access to elements
+// ------------------
+
+// x, y, z
+
+inline double & Hep3Vector::operator[] (int i)       { return operator()(i); }
+inline double   Hep3Vector::operator[] (int i) const { return operator()(i); }
+
+inline double Hep3Vector::x() const { return dx; }
+inline double Hep3Vector::y() const { return dy; }
+inline double Hep3Vector::z() const { return dz; }
+
+inline double Hep3Vector::getX() const { return dx; }
+inline double Hep3Vector::getY() const { return dy; }
+inline double Hep3Vector::getZ() const { return dz; }
+
+inline void Hep3Vector::setX(double x) { dx = x; }
+inline void Hep3Vector::setY(double y) { dy = y; }
+inline void Hep3Vector::setZ(double z) { dz = z; }
+
+inline void Hep3Vector::set(double x, double y, double z) { 
+  dx = x; 
+  dy = y; 
+  dz = z; 
+}
+
+// --------------
+// Global methods
+// --------------
+
+inline Hep3Vector operator + (const Hep3Vector & a, const Hep3Vector & b) {
+  return Hep3Vector(a.x() + b.x(), a.y() + b.y(), a.z() + b.z());
+}
+
+inline Hep3Vector operator - (const Hep3Vector & a, const Hep3Vector & b) {
+  return Hep3Vector(a.x() - b.x(), a.y() - b.y(), a.z() - b.z());
+}
+
+inline Hep3Vector operator * (const Hep3Vector & p, double a) {
+  return Hep3Vector(a*p.x(), a*p.y(), a*p.z());
+}
+
+inline Hep3Vector operator * (double a, const Hep3Vector & p) {
+  return Hep3Vector(a*p.x(), a*p.y(), a*p.z());
+}
+
+inline double operator * (const Hep3Vector & a, const Hep3Vector & b) {
+  return a.dot(b);
+}
+
+// --------------------------
+// Set in various coordinates
+// --------------------------
+
+inline void Hep3Vector::setRThetaPhi
+		  ( double r, double theta, double phi ) {
+  setSpherical (r, theta, phi); 
+}
+
+inline void Hep3Vector::setREtaPhi
+		  ( double r, double eta,  double phi ) {
+  setSpherical (r, 2*std::atan(std::exp(-eta)), phi); 
+}
+
+inline void Hep3Vector::setRhoPhiZ
+		  ( double rho, double phi, double z) {
+  setCylindrical (rho, phi, z); 
+}
+
+// ------------
+// Constructors
+// ------------
+
+inline Hep3Vector::Hep3Vector(double x, double y, double z)
+  : dx(x), dy(y), dz(z) {}
+
+inline Hep3Vector::Hep3Vector(const Hep3Vector & p)
+: dx(p.dx), dy(p.dy), dz(p.dz) {}
+
+inline Hep3Vector::~Hep3Vector() {}
+
+inline Hep3Vector & Hep3Vector::operator = (const Hep3Vector & p) {
+  dx = p.dx;
+  dy = p.dy;
+  dz = p.dz;
+  return *this;
+}
+
+// ------------------
+// Access to elements
+// ------------------
+
+// r, theta, phi
+
+inline double Hep3Vector::mag2() const { return dx*dx + dy*dy + dz*dz; }
+inline double Hep3Vector::mag()  const { return std::sqrt(mag2()); }
+inline double Hep3Vector::r()    const { return mag(); }
+
+inline double Hep3Vector::theta() 	const {
+  return dx == 0.0 && dy == 0.0 && dz == 0.0 ? 0.0 : std::atan2(perp(),dz);
+}
+inline double Hep3Vector::phi() const {
+  return dx == 0.0 && dy == 0.0 ? 0.0 : std::atan2(dy,dx);
+}
+
+inline double Hep3Vector::getR()     const { return mag();   }
+inline double Hep3Vector::getTheta() const { return theta(); }
+inline double Hep3Vector::getPhi()   const { return phi();   }
+inline double Hep3Vector::angle()    const { return theta(); }
+
+inline double Hep3Vector::cosTheta() const {
+  double ptot = mag();
+  return ptot == 0.0 ? 1.0 : dz/ptot;
+}
+
+inline double Hep3Vector::cos2Theta() const {
+  double ptot2 = mag2();
+  return ptot2 == 0.0 ? 1.0 : dz*dz/ptot2;
+}
+
+inline void Hep3Vector::setR(double r) { setMag(r); }
+
+inline void Hep3Vector::setTheta(double th) {
+  double ma   = mag();
+  double ph   = phi();
+  setX(ma*std::sin(th)*std::cos(ph));
+  setY(ma*std::sin(th)*std::sin(ph));
+  setZ(ma*std::cos(th));
+}
+
+inline void Hep3Vector::setPhi(double ph) {
+  double xy   = perp();
+  setX(xy*std::cos(ph));
+  setY(xy*std::sin(ph));
+}
+
+// perp, eta, 
+
+inline double Hep3Vector::perp2()  const { return dx*dx + dy*dy; }
+inline double Hep3Vector::perp()   const { return std::sqrt(perp2()); }
+inline double Hep3Vector::rho()    const { return perp();  }
+inline double Hep3Vector::eta()    const { return pseudoRapidity();}
+
+inline double Hep3Vector::getRho() const { return perp();  }
+inline double Hep3Vector::getEta() const { return pseudoRapidity();}
+
+inline void Hep3Vector::setPerp(double r) {
+  double p = perp();
+  if (p != 0.0) {
+    dx *= r/p;
+    dy *= r/p;
+  }
+}
+inline void Hep3Vector::setRho(double rho) { setPerp (rho); }
+
+// ----------
+// Comparison
+// ----------
+
+inline bool Hep3Vector::operator == (const Hep3Vector& v) const {
+  return (v.x()==x() && v.y()==y() && v.z()==z()) ? true : false;
+}
+
+inline bool Hep3Vector::operator != (const Hep3Vector& v) const {
+  return (v.x()!=x() || v.y()!=y() || v.z()!=z()) ? true : false;
+}
+
+inline double Hep3Vector::getTolerance () {
+  return tolerance;
+}
+
+// ----------
+// Arithmetic
+// ----------
+
+inline Hep3Vector& Hep3Vector::operator += (const Hep3Vector & p) {
+  dx += p.x();
+  dy += p.y();
+  dz += p.z();
+  return *this;
+}
+
+inline Hep3Vector& Hep3Vector::operator -= (const Hep3Vector & p) {
+  dx -= p.x();
+  dy -= p.y();
+  dz -= p.z();
+  return *this;
+}
+
+inline Hep3Vector Hep3Vector::operator - () const {
+  return Hep3Vector(-dx, -dy, -dz);
+}
+
+inline Hep3Vector& Hep3Vector::operator *= (double a) {
+  dx *= a;
+  dy *= a;
+  dz *= a;
+  return *this;
+}
+
+// -------------------
+// Combine two Vectors
+// -------------------
+
+inline double Hep3Vector::diff2(const Hep3Vector & p) const {
+  return (*this-p).mag2();
+}
+
+inline double Hep3Vector::dot(const Hep3Vector & p) const {
+  return dx*p.x() + dy*p.y() + dz*p.z();
+}
+
+inline Hep3Vector Hep3Vector::cross(const Hep3Vector & p) const {
+  return Hep3Vector(dy*p.z()-p.y()*dz, dz*p.x()-p.z()*dx, dx*p.y()-p.x()*dy);
+}
+
+inline double Hep3Vector::perp2(const Hep3Vector & p)  const {
+  double tot = p.mag2();
+  double ss  = dot(p);
+  return tot > 0.0 ? mag2()-ss*ss/tot : mag2();
+}
+
+inline double Hep3Vector::perp(const Hep3Vector & p) const {
+  return std::sqrt(perp2(p));
+}
+
+inline Hep3Vector Hep3Vector::perpPart () const {
+  return Hep3Vector (dx, dy, 0);
+}
+inline Hep3Vector Hep3Vector::project () const {
+  return Hep3Vector (0, 0, dz);
+}
+
+inline Hep3Vector Hep3Vector::perpPart (const Hep3Vector & v2) const {
+  return ( *this - project(v2) );
+}
+
+inline double Hep3Vector::angle(const Hep3Vector & q) const {
+  return std::acos(cosTheta(q));
+}
+
+inline double Hep3Vector::theta(const Hep3Vector & q) const { 
+  return angle(q); 
+}
+
+inline double Hep3Vector::azimAngle(const Hep3Vector & v2) const { 
+  return deltaPhi(v2); 
+}
+
+// ----------
+// Properties
+// ----------
+
+inline Hep3Vector Hep3Vector::unit() const {
+  double  tot = mag2();
+  Hep3Vector p(x(),y(),z());
+  return tot > 0.0 ? p *= (1.0/std::sqrt(tot)) : p;
+}
+
+inline Hep3Vector Hep3Vector::orthogonal() const {
+  double x = dx < 0.0 ? -dx : dx;
+  double y = dy < 0.0 ? -dy : dy;
+  double z = dz < 0.0 ? -dz : dz;
+  if (x < y) {
+    return x < z ? Hep3Vector(0,dz,-dy) : Hep3Vector(dy,-dx,0);
+  }else{
+    return y < z ? Hep3Vector(-dz,0,dx) : Hep3Vector(dy,-dx,0);
+  }
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/Vector/TwoVector.h
===================================================================
--- trunk/CLHEP/Vector/TwoVector.h	(revision 4)
+++ trunk/CLHEP/Vector/TwoVector.h	(revision 4)
@@ -0,0 +1,222 @@
+// -*- C++ -*-
+// CLASSDOC OFF
+// ---------------------------------------------------------------------------
+// CLASSDOC ON
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// Hep2Vector is a general 2-vector class defining vectors in two 
+// dimension using double components.   It comes from the ZOOM
+// PlaneVector class (the PhysicsVectors PlaneVector.h will typedef
+// PlaneVector to Hep2Vector).
+//
+// .SS See Also
+// ThreeVector.h
+//
+// .SS Authors
+// John Marraffino and Mark Fischler
+//
+
+#ifndef HEP_TWOVECTOR_H
+#define HEP_TWOVECTOR_H
+
+#ifdef GNUPRAGMA
+#pragma interface
+#endif
+
+#include <iostream>
+
+#include "CLHEP/Vector/defs.h" 
+#include "CLHEP/Vector/ThreeVector.h" 
+
+namespace CLHEP {
+
+// Declarations of classes and global methods
+class Hep2Vector;
+std::ostream & operator << (std::ostream &, const Hep2Vector &);
+std::istream & operator >> (std::istream &, Hep2Vector &);
+inline double operator * (const Hep2Vector & a,const Hep2Vector & b);
+inline Hep2Vector operator * (const Hep2Vector & p, double a);
+inline Hep2Vector operator * (double a, const Hep2Vector & p);
+       Hep2Vector operator / (const Hep2Vector & p, double a);
+inline Hep2Vector operator + (const Hep2Vector & a, const Hep2Vector & b);
+inline Hep2Vector operator - (const Hep2Vector & a, const Hep2Vector & b);
+
+/**
+ * @author
+ * @ingroup vector
+ */
+class Hep2Vector {
+
+public:
+
+  enum { X=0, Y=1, NUM_COORDINATES=2, SIZE=NUM_COORDINATES };
+  // Safe indexing of the coordinates when using with matrices, arrays, etc.
+
+  inline Hep2Vector( double x = 0.0, double y = 0.0 );
+  // The constructor.
+
+  inline Hep2Vector(const Hep2Vector & p);
+  // The copy constructor.
+
+  explicit Hep2Vector( const Hep3Vector & s);
+  // "demotion" constructor"
+  // WARNING -- THIS IGNORES THE Z COMPONENT OF THE Hep3Vector.
+  //		SO IN GENERAL, Hep2Vector(v)==v WILL NOT HOLD!
+
+  inline ~Hep2Vector();
+  // The destructor.
+
+  inline double x() const;
+  inline double y() const;
+  // The components in cartesian coordinate system.
+
+         double operator () (int i) const;
+  inline double operator [] (int i) const;
+  // Get components by index.  0-based.
+
+         double & operator () (int i);
+  inline double & operator [] (int i);
+  // Set components by index.  0-based.
+
+  inline void setX(double x);
+  inline void setY(double y);
+  inline void set (double x, double y);
+  // Set the components in cartesian coordinate system.
+
+  inline double phi() const;
+  // The azimuth angle.
+
+  inline double mag2() const;
+  // The magnitude squared.
+
+  inline double mag() const;
+  // The magnitude.
+
+  inline double r() const;
+  // r in polar coordinates (r, phi):  equal to mag().
+
+  inline void setPhi(double phi);
+  // Set phi keeping mag constant.
+
+  inline void setMag(double r);
+  // Set magnitude keeping phi constant.
+
+  inline void setR(double r);
+  // Set R keeping phi constant.  Same as setMag.
+
+  inline void setPolar(double r, double phi);
+  // Set by polar coordinates.
+
+  inline Hep2Vector & operator = (const Hep2Vector & p);
+  // Assignment.
+
+  inline bool operator == (const Hep2Vector & v) const;
+  inline bool operator != (const Hep2Vector & v) const;
+  // Comparisons.
+
+  int compare (const Hep2Vector & v) const;
+  bool operator > (const Hep2Vector & v) const;
+  bool operator < (const Hep2Vector & v) const;
+  bool operator>= (const Hep2Vector & v) const;
+  bool operator<= (const Hep2Vector & v) const;
+  // dictionary ordering according to y, then x component
+
+  static inline double getTolerance();
+  static double setTolerance(double tol);
+
+  double howNear (const Hep2Vector &p) const;
+  bool isNear  (const Hep2Vector & p, double epsilon=tolerance) const;
+
+  double howParallel (const Hep2Vector &p) const;
+  bool isParallel 
+		(const Hep2Vector & p, double epsilon=tolerance) const;
+
+  double howOrthogonal (const Hep2Vector &p) const;
+  bool isOrthogonal
+		(const Hep2Vector & p, double epsilon=tolerance) const;
+
+  inline Hep2Vector & operator += (const Hep2Vector &p);
+  // Addition.
+
+  inline Hep2Vector & operator -= (const Hep2Vector &p);
+  // Subtraction.
+
+  inline Hep2Vector operator - () const;
+  // Unary minus.
+
+  inline Hep2Vector & operator *= (double a);
+  // Scaling with real numbers.
+
+  inline Hep2Vector unit() const;
+  // Unit vector parallel to this.
+
+  inline Hep2Vector orthogonal() const;
+  // Vector orthogonal to this.
+
+  inline double dot(const Hep2Vector &p) const;
+  // Scalar product.
+
+  inline double angle(const Hep2Vector &) const;
+  // The angle w.r.t. another 2-vector.
+
+  void rotate(double);
+  // Rotates the Hep2Vector.
+
+  operator Hep3Vector () const;
+  // Cast a Hep2Vector as a Hep3Vector.
+
+  // The remaining methods are friends, thus defined at global scope:
+  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+  friend std::ostream & operator<< (std::ostream &, const Hep2Vector &);
+  // Output to a stream.
+
+  inline friend double operator * (const Hep2Vector & a,
+				   const Hep2Vector & b);
+  // Scalar product.
+
+  inline friend Hep2Vector operator * (const Hep2Vector & p, double a);
+  // v*c
+
+  inline friend Hep2Vector operator * (double a, const Hep2Vector & p);
+  // c*v
+
+         friend Hep2Vector operator / (const Hep2Vector & p, double a);
+  // v/c
+
+  inline friend Hep2Vector operator + (const Hep2Vector & a,
+				       const Hep2Vector & b);
+  // v1+v2
+
+  inline friend Hep2Vector operator - (const Hep2Vector & a,
+				        const Hep2Vector & b);
+  // v1-v2
+
+  enum { ZMpvToleranceTicks = 100 };
+
+private:
+
+  double dx;
+  double dy;
+  // The components.
+
+  static double tolerance;
+  // default tolerance criterion for isNear() to return true.
+
+};  // Hep2Vector
+
+static const Hep2Vector X_HAT2(1.0, 0.0);
+static const Hep2Vector Y_HAT2(0.0, 1.0);
+
+}  // namespace CLHEP
+
+#include "CLHEP/Vector/TwoVector.icc"
+
+#ifdef ENABLE_BACKWARDS_COMPATIBILITY
+//  backwards compatibility will be enabled ONLY in CLHEP 1.9
+using namespace CLHEP;
+#endif
+
+
+#endif /* HEP_TWOVECTOR_H */
Index: trunk/CLHEP/Vector/TwoVector.icc
===================================================================
--- trunk/CLHEP/Vector/TwoVector.icc	(revision 4)
+++ trunk/CLHEP/Vector/TwoVector.icc	(revision 4)
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+// 
+// This is the definitions of the inline member functions of the
+// Hep2Vector class.
+//
+
+#include <cmath>
+
+namespace CLHEP {
+
+inline double Hep2Vector::x() const {
+  return dx;
+}
+
+inline double Hep2Vector::y() const {
+  return dy;
+}
+
+inline Hep2Vector::Hep2Vector(double x, double y)
+: dx(x), dy(y) {}
+
+inline Hep2Vector::Hep2Vector( const Hep3Vector & s)
+: dx(s.x()), dy(s.y()) {}
+
+inline void Hep2Vector::setX(double x) {
+  dx = x;
+}
+
+inline void Hep2Vector::setY(double y) {
+  dy = y;
+}
+
+inline void Hep2Vector::set(double x, double y) {
+  dx = x;
+  dy = y;
+}
+
+double & Hep2Vector::operator[] (int i)       { return operator()(i); }
+double   Hep2Vector::operator[] (int i) const { return operator()(i); }
+
+inline Hep2Vector::Hep2Vector(const Hep2Vector & p)
+: dx(p.x()), dy(p.y()) {}
+
+inline Hep2Vector::~Hep2Vector() {}
+
+inline Hep2Vector & Hep2Vector::operator = (const Hep2Vector & p) {
+  dx = p.x();
+  dy = p.y();
+  return *this;
+}
+
+inline bool Hep2Vector::operator == (const Hep2Vector& v) const {
+  return (v.x()==x() && v.y()==y()) ? true : false;
+}
+
+inline bool Hep2Vector::operator != (const Hep2Vector& v) const {
+  return (v.x()!=x() || v.y()!=y()) ? true : false;
+}
+
+inline Hep2Vector& Hep2Vector::operator += (const Hep2Vector & p) {
+  dx += p.x();
+  dy += p.y();
+  return *this;
+}
+
+inline Hep2Vector& Hep2Vector::operator -= (const Hep2Vector & p) {
+  dx -= p.x();
+  dy -= p.y();
+  return *this;
+}
+
+inline Hep2Vector Hep2Vector::operator - () const {
+  return Hep2Vector(-dx, -dy);
+}
+
+inline Hep2Vector& Hep2Vector::operator *= (double a) {
+  dx *= a;
+  dy *= a;
+  return *this;
+}
+
+inline double Hep2Vector::dot(const Hep2Vector & p) const {
+  return dx*p.x() + dy*p.y();
+}
+
+inline double Hep2Vector::mag2() const {
+  return dx*dx + dy*dy;
+}
+
+inline double Hep2Vector::mag() const {
+  return std::sqrt(mag2());
+}
+
+inline double Hep2Vector::r() const {
+  return std::sqrt(mag2());
+}
+
+inline Hep2Vector Hep2Vector::unit() const {
+  double tot = mag2();
+  Hep2Vector p(*this);
+  return tot > 0.0 ? p *= (1.0/std::sqrt(tot)) : Hep2Vector(1,0);
+}
+
+inline Hep2Vector Hep2Vector::orthogonal() const {
+  double x = std::fabs(dx), y = std::fabs(dy);
+  if (x < y) {
+    return Hep2Vector(dy,-dx);
+  }else{
+    return Hep2Vector(-dy,dx);
+  }
+}
+
+inline double Hep2Vector::phi() const {
+  return dx == 0.0 && dy == 0.0 ? 0.0 : std::atan2(dy,dx);
+}
+
+inline double Hep2Vector::angle(const Hep2Vector & q) const {
+  double ptot2 = mag2()*q.mag2();
+  return ptot2 <= 0.0 ? 0.0 : std::acos(dot(q)/std::sqrt(ptot2));
+}
+
+inline void Hep2Vector::setMag(double r){
+  double ph = phi();
+  setX( r * std::cos(ph) );
+  setY( r * std::sin(ph) );
+}
+
+inline void Hep2Vector::setR(double r){
+  setMag(r);
+}
+
+inline void Hep2Vector::setPhi(double phi){
+  double ma = mag();
+  setX( ma * std::cos(phi) );
+  setY( ma * std::sin(phi) );
+}
+
+inline void Hep2Vector::setPolar(double r, double phi){
+  setX( r * std::cos(phi) );
+  setY( r * std::sin(phi) );
+}
+
+inline Hep2Vector operator + (const Hep2Vector & a, const Hep2Vector & b) {
+  return Hep2Vector(a.x() + b.x(), a.y() + b.y());
+}
+
+inline Hep2Vector operator - (const Hep2Vector & a, const Hep2Vector & b) {
+  return Hep2Vector(a.x() - b.x(), a.y() - b.y());
+}
+
+inline Hep2Vector operator * (const Hep2Vector & p, double a) {
+  return Hep2Vector(a*p.x(), a*p.y());
+}
+
+inline Hep2Vector operator * (double a, const Hep2Vector & p) {
+  return Hep2Vector(a*p.x(), a*p.y());
+}
+
+inline double operator * (const Hep2Vector & a, const Hep2Vector & b) {
+  return a.dot(b);
+}
+
+inline double Hep2Vector::getTolerance () {
+  return tolerance;
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/Vector/ZMxpv.h
===================================================================
--- trunk/CLHEP/Vector/ZMxpv.h	(revision 4)
+++ trunk/CLHEP/Vector/ZMxpv.h	(revision 4)
@@ -0,0 +1,234 @@
+#ifndef HEP_ZMXPV_H
+#define HEP_ZMXPV_H
+
+// ----------------------------------------------------------------------
+//
+//  ZMxpv.h    	ZMexception's ZMthrown by classes in the PhysicsVectors
+//		package.  To avoid name clashes, these start with ZMxpv.
+//
+//  THIS FILE CONTAINS TWO VERSIONS OF THE NECESSARY CODE:
+//
+//  With no special defines, this file will produce code for pure CLHEP 
+//  building -- no ZOOM Exceptions are involved.
+//
+//  To force a build using ZOOM Exceptions where the ZMthrow macros appear,
+//  compile with ENABLE_ZOOM_EXCEPTIONS defined.
+//
+// ----------------------------------------------------------------------
+
+//#undef  ENABLE_ZOOM_EXCEPTIONS 	// For CLHEP builds 
+//#define ENABLE_ZOOM_EXCEPTIONS    	// For ZOOM  builds
+
+// There should be some external way to control this.  We haven't found it yet.
+// Right now, this must be changed by hand when going between CLHEP and ZOOM.
+#undef  ENABLE_ZOOM_EXCEPTIONS 	
+
+  // Member functions of the Vector classes are capable of ZMthrow-ing the
+  // following ZMexception's:
+  //
+  //	ZMxPhysicsVectors	Severe	Parent exception of all ZMexceptions
+  //					particular to classes in the package.
+  //
+  //    ZMxpvInfiniteVector     Error
+  //                                    Mathematical operation will lead
+  //                                    to infinity or NAN in a component
+  //                                    of a result vector.
+  //    ZMxpvZeroVector         Error
+  //                                    A zero vector was used to specify
+  //                                    a direction based on vector.unit().
+  //    ZMxpvTachyonic          Error
+  //                                    A relativistic kinematic function was
+  //                                    taken, involving a vector representing
+  //                                    a speed at or beyond that of light (=1).
+  //	ZMxpvSpacelike		Error
+  //					A spacelike 4-vector was used in a
+  //					context where its restMass or gamma
+  //					needs to be computed:  The result is
+  //					formally imaginary (a zero result is
+  //					supplied).
+  //    ZMxpvInfinity 		Error
+  //                                    Mathematical operation will lead
+  //                                    to infinity as a Scalar result.
+  //    ZMxpvNegativeMass	Error
+  //                                    Kinematic operation, e.g. invariant
+  //					mass, rendered meaningless by an input
+  //					with negative time component.
+  //	ZMxpvVectorInputFails	Error
+  //					Input to a SpaceVector or Lorentz
+  //					Vector failed due to bad format or EOF.
+  //	ZMxpvParallelCols	Error
+  //					Purportedly orthogonal col's supplied
+  //					to form a Rotation are exactly
+  //					parallel instead.
+  //	ZMxpvImproperRotation	Error
+  //					Orthogonal col's supplied form a
+  //					refection (determinant -1) more
+  //					nearly than rather than a rotation.
+  //	ZMxpvImproperTransformation Error
+  //                                    Orthogonalized rows supplied form a
+  //                                    tachyonic boost, a reflection, or
+  //                                    a combination of those flaws,
+  //                                    more nearly than a proper Lorentz
+  //                                    transformation.
+  //	ZMxpvFixedAxis		Error
+  //					Attempt to change a RotationX,
+  //					RotationY, or RotationZ in such a way
+  //					that the axis might no longer be X,
+  //					Y, or Z respectively.
+  //	ZMxpvIndexRange		Error
+  //					When using the syntax of v(i) to get
+  //					a vector component, i is out of range.
+  //	ZMxpvNotOrthogonal	Warning
+  //					Purportedly orthogonal col's supplied
+  //					to form a Rotation or LT are not
+  //					orthogonal within the tolerance.
+  //	ZMxpvNotSymplectic	Warning
+  //					A row supplied to form a Lorentz
+  //					transformation has a value of restmass
+  //					incorrect by more than the tolerance:
+  //					It should be -1 for rows 1-3,
+  //					+1 for row 4.
+  //    ZMxpvAmbiguousAngle     Warning
+  //                                    Method involves taking an angle against
+  //                                    a reference vector of zero length, or
+  //                                    phi in polar coordinates of a vector
+  //                                    along the Z axis.
+  //    ZMxpvNegativeR          Warning
+  //                                    R of a supplied vector is negative.
+  //                                    The mathematical operation done is
+  //                                    still formally valid.
+  //    ZMxpvUnusualTheta       Warning
+  //                                    Theta supplied to construct or set
+  //                                    a vector is outside the range [0,PI].
+  //                                    The mathematical operation done is
+  //                                    still formally valid.  But note that
+  //                                    when sin(theta) < 0, phi becomes an
+  //                                    angle against the -X axis.
+  //______________________________________________________________________
+
+#ifndef ENABLE_ZOOM_EXCEPTIONS 
+
+//  This is the CLHEP version.  When compiled for CLHEP, the basic CLHEP 
+//  Vector classes will not (at least for now) depend on ZOOM Exceptions.  
+//  Though this header lists the various sorts of Exceptions that could be 
+//  thrown, ZMthrow.h in the pure CLHEP context will make ZMthrowC  
+//  do what CLHEP has always done:  whine to cerr about the problem 
+//  and continue.
+//  ZMthrowA will whine to cerr and throw an exception; by catching the
+//  exception as a std::exception, the outside code can call e.what() to 
+//  find the message string.
+//
+//	If CLHEP ever embraces the ZOOM Exceptions mechanism, we will simply
+//	modify this file.
+
+#include <string>
+#include <exception>
+
+#define ZMthrowA(A) do { std::cerr << A.name() << " thrown:\n" 	   \
+             <<   A.what() << "\n" 					   \
+	     << "at line " << __LINE__ << " in file " << __FILE__ << "\n"; \
+  throw A;} while (0)
+
+#define ZMthrowC(A) do { std::cerr << A.name() << ":\n" 		   \
+             <<   A.what() << "\n" 					   \
+	     << "at line " << __LINE__ << " in file " << __FILE__ << "\n"; \
+  } while (0)
+
+class CLHEP_vector_exception : public std::exception {
+public:
+    CLHEP_vector_exception ( const std::string & s ) throw();
+    virtual const char* what() const throw();
+    virtual const char* name() const throw() = 0; 
+    virtual ~CLHEP_vector_exception() throw() {} 
+  private:								
+    std::string message;  
+};
+
+#define CLHEP_vector_exception_header(NAME) 				\
+  class NAME : public CLHEP_vector_exception {				\
+  public:								\
+    NAME ( const std::string & s ) throw();				\
+    virtual const char* name() const throw();  				\
+    virtual ~NAME() throw() {}						\
+  };
+
+
+// The following exceptions might be encountered via ZMtrhowA
+
+CLHEP_vector_exception_header( ZMxPhysicsVectors )
+CLHEP_vector_exception_header( ZMxpvSpacelike )
+CLHEP_vector_exception_header( ZMxpvNegativeMass )
+CLHEP_vector_exception_header( ZMxpvVectorInputFails )
+CLHEP_vector_exception_header( ZMxpvIndexRange )
+CLHEP_vector_exception_header( ZMxpvFixedAxis )
+
+// The following are sometimes ZMthrowA and sometimes ZMthrowC
+
+CLHEP_vector_exception_header( ZMxpvTachyonic )
+CLHEP_vector_exception_header( ZMxpvZeroVector )
+CLHEP_vector_exception_header( ZMxpvImproperTransformation )
+CLHEP_vector_exception_header( ZMxpvInfiniteVector )
+CLHEP_vector_exception_header( ZMxpvInfinity )
+CLHEP_vector_exception_header( ZMxpvImproperRotation )
+CLHEP_vector_exception_header( ZMxpvAmbiguousAngle )
+
+// THe following won't throw; they are encountered via ZMthrowC
+
+CLHEP_vector_exception_header( ZMxpvNegativeR )
+CLHEP_vector_exception_header( ZMxpvUnusualTheta )
+CLHEP_vector_exception_header( ZMxpvParallelCols )
+CLHEP_vector_exception_header( ZMxpvNotOrthogonal )
+CLHEP_vector_exception_header( ZMxpvNotSymplectic )
+
+#endif // endif for ifndef ENABLE_ZOOM_EXCEPTIONS 
+
+// =============================================================
+// =============================================================
+// =============================================================
+
+#ifdef ENABLE_ZOOM_EXCEPTIONS 
+
+//  This is the ZOOM version.  When compiled for ZOOM, even the basic CLHEP 
+//  Vector classes will depend on ZOOM Exceptions.  
+//  Though in the CLHEP context methods use ZMthrowA and ZMthrowC, these
+//  in the ZOOM context become ZMthrow.
+//
+//  Either this file or ZMxpvCLHEP.h is copied to become ZMxpv.h, depending 
+//  on whether this is a ZOOM or a CLHEP build.  
+//
+
+#ifndef ZMEXCEPTIONS_H
+  #include "Exceptions/ZMexception.h"
+  #include "Exceptions/ZMthrow.h"
+#endif
+using namespace zmex;
+
+namespace zmpv  {
+
+ZMexStandardDefinition (ZMexception, ZMxPhysicsVectors);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvInfiniteVector);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvZeroVector);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvTachyonic);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvSpacelike);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvInfinity);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvNegativeMass);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvAmbiguousAngle);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvNegativeR);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvUnusualTheta);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvVectorInputFails);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvParallelCols);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvImproperRotation);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvImproperTransformation);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvIndexRange);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvNotOrthogonal);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvNotSymplectic);
+ZMexStandardDefinition (ZMxPhysicsVectors, ZMxpvFixedAxis);
+
+#define ZMthrowA(A) ZMthrow(A)
+#define ZMthrowC(A) ZMthrow(A)
+
+}  // namespace zmpv
+
+#endif // ENABLE_ZOOM_EXCEPTIONS
+
+#endif // HEP_ZMXPV_H
Index: trunk/CLHEP/Vector/defs.h
===================================================================
--- trunk/CLHEP/Vector/defs.h	(revision 4)
+++ trunk/CLHEP/Vector/defs.h	(revision 4)
@@ -0,0 +1,45 @@
+/* Vector/defs.h.  Generated by configure.  */
+/* Vector/defs.h.in.  Generated from configure.in by autoheader.  */
+
+#ifndef VECTOR_DEFS_H
+#define VECTOR_DEFS_H
+
+/* Name of package */
+#ifndef PACKAGE
+#define PACKAGE "Vector"
+#endif
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef PACKAGE_BUGREPORT
+#define PACKAGE_BUGREPORT "http://savannah.cern.ch/projects/clhep/"
+#endif
+
+/* Define to the full name of this package. */
+#ifndef PACKAGE_NAME
+#define PACKAGE_NAME "CLHEP Vector"
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef PACKAGE_STRING
+#define PACKAGE_STRING "CLHEP Vector 2.0.3.0"
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef PACKAGE_TARNAME
+#define PACKAGE_TARNAME "Vector"
+#endif
+
+/* Define to the version of this package. */
+#ifndef PACKAGE_VERSION
+#define PACKAGE_VERSION "2.0.3.0"
+#endif
+
+/* building with Visual C++ */
+/* #undef USING_VISUAL */
+
+/* Version number of package */
+#ifndef VERSION
+#define VERSION "2.0.3.0"
+#endif
+
+#endif  // VECTOR_DEFS_H
Index: trunk/CLHEP/Vector/defs.h.in
===================================================================
--- trunk/CLHEP/Vector/defs.h.in	(revision 4)
+++ trunk/CLHEP/Vector/defs.h.in	(revision 4)
@@ -0,0 +1,44 @@
+/* Vector/defs.h.in.  Generated from configure.in by autoheader.  */
+
+#ifndef VECTOR_DEFS_H
+#define VECTOR_DEFS_H
+
+/* Name of package */
+#ifndef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef PACKAGE_BUGREPORT
+#undef PACKAGE_BUGREPORT
+#endif
+
+/* Define to the full name of this package. */
+#ifndef PACKAGE_NAME
+#undef PACKAGE_NAME
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef PACKAGE_STRING
+#undef PACKAGE_STRING
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef PACKAGE_TARNAME
+#undef PACKAGE_TARNAME
+#endif
+
+/* Define to the version of this package. */
+#ifndef PACKAGE_VERSION
+#undef PACKAGE_VERSION
+#endif
+
+/* building with Visual C++ */
+#undef USING_VISUAL
+
+/* Version number of package */
+#ifndef VERSION
+#undef VERSION
+#endif
+
+#endif  // VECTOR_DEFS_H
Index: trunk/CLHEP/src/AxisAngle.cc
===================================================================
--- trunk/CLHEP/src/AxisAngle.cc	(revision 4)
+++ trunk/CLHEP/src/AxisAngle.cc	(revision 4)
@@ -0,0 +1,106 @@
+// ----------------------------------------------------------------------
+//
+// AxisAngle.cc
+//
+// History:
+//   23-Jan-1998  WEB  Initial draft
+//   13-Mar-1998  WEB  Corrected ZMpvAxisAngleRep
+//   15-Jun-1998  WEB  Added namespace support
+//   26-Jul-2000  MF  CLHEP version
+//   12-Apr-2001  MF  NaN-proofing
+//
+// ----------------------------------------------------------------------
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/AxisAngle.h"
+
+namespace CLHEP  {
+
+double HepAxisAngle::tolerance = Hep3Vector::ToleranceTicks * 1.0e-08;
+
+static void ZMpvAxisAngleRep( const HepAxisAngle & aa, double array[] ) {
+
+  register double sinDelta = sin( aa.delta() );
+  register double cosDelta = cos( aa.delta() );
+  register double oneMinusCosDelta = 1.0 - cosDelta;
+
+  register double uX = aa.getAxis().getX();
+  register double uY = aa.getAxis().getY();
+  register double uZ = aa.getAxis().getZ();
+
+  array[0] = oneMinusCosDelta * uX * uX  +  cosDelta;
+  array[1] = oneMinusCosDelta * uX * uY  -  sinDelta * uZ;
+  array[2] = oneMinusCosDelta * uX * uZ  +  sinDelta * uY;
+
+  array[3] = oneMinusCosDelta * uY * uX  +  sinDelta * uZ;
+  array[4] = oneMinusCosDelta * uY * uY  +  cosDelta;
+  array[5] = oneMinusCosDelta * uY * uZ  -  sinDelta * uX;
+
+  array[6] = oneMinusCosDelta * uZ * uX  -  sinDelta * uY;
+  array[7] = oneMinusCosDelta * uZ * uY  +  sinDelta * uX;
+  array[8] = oneMinusCosDelta * uZ * uZ  +  cosDelta;
+
+} // ZMpvAxisAngleRep
+
+
+double HepAxisAngle::distance( const AA & aa ) const  {
+
+  double thisRep[9];
+  double aaRep[9];
+
+  ZMpvAxisAngleRep( *this, thisRep );
+  ZMpvAxisAngleRep( aa,    aaRep );
+
+  double sum = 0.0;
+  for ( int i = 0; i < 9; i++ )  {
+    sum += thisRep[i] * aaRep[i];
+  }
+
+  double d = 3.0 - sum;		// NaN-proofing: 
+  return  (d >= 0) ? d : 0;             // sqrt(distance) is used in howNear()
+
+}  // HepAxisAngle::distance()
+
+
+bool HepAxisAngle::isNear( const AA & aa, Scalar epsilon ) const  {
+
+  return  distance( aa ) <= epsilon * epsilon;
+
+}  // HepAxisAngle::isNear()
+
+
+double HepAxisAngle::howNear( const AA & aa ) const  {
+
+  return  sqrt( distance( aa ) );
+
+}  // HepAxisAngle::howNear()
+
+
+//-********************
+//
+// Global methods
+//
+//-********************
+
+
+std::ostream & operator<<(std::ostream & os, const HepAxisAngle & aa) {
+  os << '(' << aa.axis() << ", " << aa.delta() << ')';
+  return  os;
+}  // operator<<()
+
+
+void ZMinputAxisAngle ( std::istream & is, 
+			double & x, double & y, double & z, 
+                       	double & delta );
+
+std::istream & operator>>(std::istream & is, HepAxisAngle & aa) {
+  Hep3Vector axis;
+  double delta;
+  double x,y,z;
+  ZMinputAxisAngle ( is, x, y, z, delta );
+  axis.set(x,y,z);
+  aa.set ( axis, delta );
+  return  is;
+}  // operator>>()
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/Boost.cc
===================================================================
--- trunk/CLHEP/src/Boost.cc	(revision 4)
+++ trunk/CLHEP/src/Boost.cc	(revision 4)
@@ -0,0 +1,260 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepBoost class.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Boost.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+HepBoost & HepBoost::set (double bx, double by, double bz) {
+  double bp2 = bx*bx + by*by + bz*bz;
+  if (bp2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Boost Vector supplied to set HepBoost represents speed >= c."));
+  }    
+  double gamma = 1.0 / sqrt(1.0 - bp2);
+  double bgamma = gamma * gamma / (1.0 + gamma);
+  rep_.xx_ = 1.0 + bgamma * bx * bx;
+  rep_.yy_ = 1.0 + bgamma * by * by;
+  rep_.zz_ = 1.0 + bgamma * bz * bz;
+  rep_.xy_ = bgamma * bx * by;
+  rep_.xz_ = bgamma * bx * bz;
+  rep_.yz_ = bgamma * by * bz;
+  rep_.xt_ = gamma * bx;
+  rep_.yt_ = gamma * by;
+  rep_.zt_ = gamma * bz;
+  rep_.tt_ = gamma;
+  return *this;
+}
+
+HepBoost & HepBoost::set (const HepRep4x4Symmetric & m) {
+  rep_ = m;
+  return *this;
+}
+
+HepBoost & HepBoost::set (Hep3Vector direction, double beta) {
+  double length = direction.mag();
+  if (length <= 0) {				// Nan-proofing
+    ZMthrowA (ZMxpvZeroVector(
+    "Direction supplied to set HepBoost is zero."));
+    set (0,0,0);
+    return *this;
+  }    
+  set(beta*direction.x()/length,
+      beta*direction.y()/length,
+      beta*direction.z()/length);
+  return *this;
+}
+
+HepBoost & HepBoost::set (const Hep3Vector & boost) {
+  return set (boost.x(), boost.y(), boost.z());
+}
+
+// ----------  Accessors:
+
+// ----------  Decomposition:
+
+void HepBoost::decompose (HepRotation & rotation, HepBoost & boost) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoost::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+void HepBoost::decompose (HepBoost & boost, HepRotation & rotation) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoost::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+// ----------  Comparisons:
+
+double HepBoost::distance2( const HepRotation & r ) const {
+  double db2 = norm2();
+  double dr2  = r.norm2();
+  return (db2 + dr2);
+}
+
+double HepBoost::distance2( const HepLorentzRotation & lt ) const {
+  HepBoost b1;
+  HepRotation r1;
+  lt.decompose(b1,r1);
+  double db2 = distance2(b1);
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+double HepBoost::howNear ( const HepRotation & r  ) const {
+  return sqrt(distance2(r));
+}
+
+double HepBoost::howNear ( const HepLorentzRotation & lt  ) const {
+  return sqrt(distance2(lt));
+}
+
+bool HepBoost::isNear (const HepRotation & r, double epsilon) const {
+  double db2 = norm2();
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r.norm2();
+  return (db2+dr2 <= epsilon*epsilon);
+}
+
+bool HepBoost::isNear (const HepLorentzRotation & lt, 
+			           double epsilon) const {
+  HepBoost b1;
+  HepRotation r1;
+  double db2 = distance2(b1);
+  lt.decompose(b1,r1);
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+// ----------  Properties:
+
+double HepBoost::norm2() const {
+  register double bgx = rep_.xt_;
+  register double bgy = rep_.yt_;
+  register double bgz = rep_.zt_;
+  return bgx*bgx+bgy*bgy+bgz*bgz;
+}
+
+void HepBoost::rectify() {
+  // Assuming the representation of this is close to a true pure boost,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" pure boost matrix for the LT again.
+
+  // The natural way to do this is to use the t column as a boost and set 
+  // based on that boost vector.
+  
+  // There is perhaps danger that this boost vector will appear equal to or 
+  // greater than a unit vector; the best we can do for such a case is use
+  // a boost in that direction but rescaled to just less than one.
+
+  // There is in principle no way that gamma could have become negative,
+  // but if that happens, we ZMthrow and (if continuing) just rescale, which
+  // will change the sign of the last column when computing the boost.
+
+  double gam = tt();
+  if (gam <= 0) {				    // 4/12/01 mf 
+//  ZMthrowA (ZMxpvTachyonic(
+    ZMthrowC (ZMxpvTachyonic(
+    "Attempt to rectify a boost with non-positive gamma."));
+    if (gam==0) return;				    // NaN-proofing
+  }    
+  Hep3Vector boost (xt(), yt(), zt());
+  boost /= tt();
+  if ( boost.mag2() >= 1 ) {			    // NaN-proofing:
+    boost /= ( boost.mag() * ( 1.0 + 1.0e-16 ) );   // used to just check > 1
+  }
+  set ( boost );
+}
+
+// ---------- Application is all in .icc 
+
+// ---------- Operations in the group of 4-Rotations
+
+HepLorentzRotation
+HepBoost::matrixMultiplication(const HepRep4x4 & m) const {
+  HepRep4x4Symmetric r = rep4x4Symmetric();
+  return HepLorentzRotation( HepRep4x4 (
+    r.xx_*m.xx_ + r.xy_*m.yx_ + r.xz_*m.zx_ + r.xt_*m.tx_,
+    r.xx_*m.xy_ + r.xy_*m.yy_ + r.xz_*m.zy_ + r.xt_*m.ty_,
+    r.xx_*m.xz_ + r.xy_*m.yz_ + r.xz_*m.zz_ + r.xt_*m.tz_,
+    r.xx_*m.xt_ + r.xy_*m.yt_ + r.xz_*m.zt_ + r.xt_*m.tt_,
+
+    r.xy_*m.xx_ + r.yy_*m.yx_ + r.yz_*m.zx_ + r.yt_*m.tx_,
+    r.xy_*m.xy_ + r.yy_*m.yy_ + r.yz_*m.zy_ + r.yt_*m.ty_,
+    r.xy_*m.xz_ + r.yy_*m.yz_ + r.yz_*m.zz_ + r.yt_*m.tz_,
+    r.xy_*m.xt_ + r.yy_*m.yt_ + r.yz_*m.zt_ + r.yt_*m.tt_,
+
+    r.xz_*m.xx_ + r.yz_*m.yx_ + r.zz_*m.zx_ + r.zt_*m.tx_,
+    r.xz_*m.xy_ + r.yz_*m.yy_ + r.zz_*m.zy_ + r.zt_*m.ty_,
+    r.xz_*m.xz_ + r.yz_*m.yz_ + r.zz_*m.zz_ + r.zt_*m.tz_,
+    r.xz_*m.xt_ + r.yz_*m.yt_ + r.zz_*m.zt_ + r.zt_*m.tt_,
+
+    r.xt_*m.xx_ + r.yt_*m.yx_ + r.zt_*m.zx_ + r.tt_*m.tx_,
+    r.xt_*m.xy_ + r.yt_*m.yy_ + r.zt_*m.zy_ + r.tt_*m.ty_,
+    r.xt_*m.xz_ + r.yt_*m.yz_ + r.zt_*m.zz_ + r.tt_*m.tz_,
+    r.xt_*m.xt_ + r.yt_*m.yt_ + r.zt_*m.zt_ + r.tt_*m.tt_) );
+}
+
+HepLorentzRotation
+HepBoost::matrixMultiplication(const HepRep4x4Symmetric & m) const {
+  HepRep4x4Symmetric r = rep4x4Symmetric();
+  return HepLorentzRotation( HepRep4x4 (
+    r.xx_*m.xx_ + r.xy_*m.xy_ + r.xz_*m.xz_ + r.xt_*m.xt_,
+    r.xx_*m.xy_ + r.xy_*m.yy_ + r.xz_*m.yz_ + r.xt_*m.yt_,
+    r.xx_*m.xz_ + r.xy_*m.yz_ + r.xz_*m.zz_ + r.xt_*m.zt_,
+    r.xx_*m.xt_ + r.xy_*m.yt_ + r.xz_*m.zt_ + r.xt_*m.tt_,
+
+    r.xy_*m.xx_ + r.yy_*m.xy_ + r.yz_*m.xz_ + r.yt_*m.xt_,
+    r.xy_*m.xy_ + r.yy_*m.yy_ + r.yz_*m.yz_ + r.yt_*m.yt_,
+    r.xy_*m.xz_ + r.yy_*m.yz_ + r.yz_*m.zz_ + r.yt_*m.zt_,
+    r.xy_*m.xt_ + r.yy_*m.yt_ + r.yz_*m.zt_ + r.yt_*m.tt_,
+
+    r.xz_*m.xx_ + r.yz_*m.xy_ + r.zz_*m.xz_ + r.zt_*m.xt_,
+    r.xz_*m.xy_ + r.yz_*m.yy_ + r.zz_*m.yz_ + r.zt_*m.yt_,
+    r.xz_*m.xz_ + r.yz_*m.yz_ + r.zz_*m.zz_ + r.zt_*m.zt_,
+    r.xz_*m.xt_ + r.yz_*m.yt_ + r.zz_*m.zt_ + r.zt_*m.tt_,
+
+    r.xt_*m.xx_ + r.yt_*m.xy_ + r.zt_*m.xz_ + r.tt_*m.xt_,
+    r.xt_*m.xy_ + r.yt_*m.yy_ + r.zt_*m.yz_ + r.tt_*m.yt_,
+    r.xt_*m.xz_ + r.yt_*m.yz_ + r.zt_*m.zz_ + r.tt_*m.zt_,
+    r.xt_*m.xt_ + r.yt_*m.yt_ + r.zt_*m.zt_ + r.tt_*m.tt_) );
+}
+
+HepLorentzRotation
+HepBoost::operator* (const HepLorentzRotation & lt) const {
+  return matrixMultiplication(lt.rep4x4());
+}
+
+HepLorentzRotation
+HepBoost::operator* (const HepBoost & b) const {
+  return matrixMultiplication(b.rep_);
+}
+
+HepLorentzRotation
+HepBoost::operator* (const HepRotation & r) const {
+  return matrixMultiplication(r.rep4x4());
+}
+
+// ---------- I/O:
+
+std::ostream & HepBoost::print( std::ostream & os ) const {
+  if ( rep_.tt_ <= 1 ) {
+    os << "Lorentz Boost( IDENTITY )";
+  } else {
+    double norm = boostVector().mag();
+    os << "\nLorentz Boost " << boostVector()/norm <<
+          "\n{beta = " << beta() << " gamma = " << gamma() << "}\n";
+  }
+  return os;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/BoostX.cc
===================================================================
--- trunk/CLHEP/src/BoostX.cc	(revision 4)
+++ trunk/CLHEP/src/BoostX.cc	(revision 4)
@@ -0,0 +1,165 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepBoostX class.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/BoostX.h"
+#include "CLHEP/Vector/Boost.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+
+// ----------  Constructors and Assignment:
+
+HepBoostX & HepBoostX::set (double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to set HepBoostX represents speed >= c."));
+    beta_  = 1.0 - 1.0E-8;		// NaN-proofing
+    gamma_ = 1.0 / sqrt(1.0 - b2);
+    return *this;
+  }    
+  beta_  = beta;
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+  return *this;
+}
+
+// ----------  Accessors:
+
+HepRep4x4 HepBoostX::rep4x4() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4( gamma_,   0,    0,    bg,
+                      0,      1,    0,    0,
+                      0,      0,    1,    0,
+                     bg,      0,    0,  gamma_ );
+}
+
+HepRep4x4Symmetric HepBoostX::rep4x4Symmetric() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4Symmetric( gamma_,   0,    0,    bg,
+                            	       1,    0,    0,
+                                    	     1,    0,
+                                        	 gamma_ );
+}
+
+// ----------  Decomposition:
+
+void HepBoostX::decompose (HepRotation & rotation, HepBoost & boost) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostX::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+void HepBoostX::decompose (HepBoost & boost, HepRotation & rotation) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostX::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+// ----------  Comparisons:
+
+double HepBoostX::distance2( const HepBoost & b ) const {
+  return b.distance2(*this);
+}
+
+double HepBoostX::distance2( const HepRotation & r ) const {
+  double db2 = norm2();
+  double dr2  = r.norm2();
+  return (db2 + dr2);
+}
+
+double HepBoostX::distance2( const HepLorentzRotation & lt ) const {
+  HepBoost b1;
+  HepRotation r1;
+  lt.decompose(b1,r1);
+  double db2 = distance2(b1);
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+bool HepBoostX::isNear (const HepRotation & r, double epsilon) const {
+  double db2 = norm2();
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r.norm2();
+  return (db2+dr2 <= epsilon*epsilon);
+}
+
+bool HepBoostX::isNear ( const HepLorentzRotation & lt,
+				     double epsilon) const {
+  HepBoost b1;
+  HepRotation r1;
+  double db2 = distance2(b1);
+  lt.decompose(b1,r1);
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+// ----------  Properties:
+
+void HepBoostX::rectify() {
+  // Assuming the representation of this is close to a true pure boost,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" pure boostX matrix for again.
+  
+  double b2 = beta_*beta_;
+  if (b2 >= 1) {
+    beta_ = 1.0 - 1.0e-8;		// NaN-proofing
+    b2 = beta_*beta_;
+  } 
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+}
+
+// ---------- Application:
+
+// ---------- Operations in the group of 4-Rotations
+
+HepBoostX HepBoostX::operator * (const HepBoostX & b) const {
+  return HepBoostX ( (beta()+b.beta()) / (1+beta()*b.beta()) );
+}
+HepLorentzRotation HepBoostX::operator * (const HepBoost & b) const {
+  HepLorentzRotation me (*this);
+  return me*b;
+}
+HepLorentzRotation HepBoostX::operator * (const HepRotation & r) const {
+  HepLorentzRotation me (*this);
+  return me*r;
+}
+HepLorentzRotation HepBoostX::operator * (const HepLorentzRotation & lt) const {
+  HepLorentzRotation me (*this);
+  return me*lt;
+}
+
+// ---------- I/O:
+ 
+std::ostream & HepBoostX::print( std::ostream & os ) const {
+  os << "Boost in X direction (beta = " << beta_ 
+			<< ", gamma = " << gamma_ << ") ";
+  return os;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/BoostY.cc
===================================================================
--- trunk/CLHEP/src/BoostY.cc	(revision 4)
+++ trunk/CLHEP/src/BoostY.cc	(revision 4)
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepBoostY class.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/BoostY.h"
+#include "CLHEP/Vector/Boost.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+HepBoostY & HepBoostY::set (double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to set HepBoostY represents speed >= c."));
+    beta_  = 1.0 - 1.0E-8;              // NaN-proofing
+    gamma_ = 1.0 / sqrt(1.0 - b2);
+    return *this;
+  }    
+  beta_  = beta;
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+  return *this;
+}
+
+// ----------  Accessors:
+
+HepRep4x4 HepBoostY::rep4x4() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4(   1,      0,    0,    0, 
+		      0,    gamma_, 0,    bg,
+                      0,      0,    1,    0,
+		      0,     bg,    0,  gamma_ );
+}
+
+HepRep4x4Symmetric HepBoostY::rep4x4Symmetric() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4Symmetric (   1,      0,    0,    0, 
+		                      gamma_, 0,    bg,
+                      		 	      1,    0,
+		                                  gamma_ );
+}
+
+// ----------  Decomposition:
+
+void HepBoostY::decompose (HepRotation & rotation, HepBoost & boost) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostY::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+void HepBoostY::decompose (HepBoost & boost, HepRotation & rotation) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostY::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+// ----------  Comparisons:
+
+double HepBoostY::distance2( const HepBoost & b ) const {
+  return b.distance2(*this);
+}
+
+double HepBoostY::distance2( const HepRotation & r ) const {
+  double db2 = norm2();
+  double dr2  = r.norm2();
+  return (db2 + dr2);
+}
+
+double HepBoostY::distance2( const HepLorentzRotation & lt ) const {
+  HepBoost b1;
+  HepRotation r1;
+  lt.decompose(b1,r1);
+  double db2 = distance2(b1);
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+bool HepBoostY::isNear (const HepRotation & r, double epsilon) const {
+  double db2 = norm2();
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r.norm2();
+  return (db2+dr2 <= epsilon*epsilon);
+}
+
+bool HepBoostY::isNear ( const HepLorentzRotation & lt, 
+					double epsilon  ) const {
+  HepBoost b1;
+  HepRotation r1;
+  double db2 = distance2(b1);
+  lt.decompose(b1,r1);
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+// ----------  Properties:
+
+void HepBoostY::rectify() {
+  // Assuming the representation of this is close to a true pure boost,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" pure BoostY matrix for again.
+  
+  double b2 = beta_*beta_;
+  if (b2 >= 1) {
+    beta_ = 1.0 - 1.0e-8;		// Nan-proofing
+    b2 = beta_*beta_;
+  } 
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+}
+
+// ---------- Application:
+
+// ---------- Operations in the group of 4-Rotations
+
+HepBoostY HepBoostY::operator * (const HepBoostY & b) const {
+  return HepBoostY ( (beta()+b.beta()) / (1+beta()*b.beta()) );
+}
+HepLorentzRotation HepBoostY::operator * (const HepBoost & b) const {
+  HepLorentzRotation me (*this);
+  return me*b;
+}
+HepLorentzRotation HepBoostY::operator * (const HepRotation & r) const {
+  HepLorentzRotation me (*this);
+  return me*r;
+}
+HepLorentzRotation HepBoostY::operator * (const HepLorentzRotation & lt) const {
+  HepLorentzRotation me (*this);
+  return me*lt;
+}
+ 
+// ---------- I/O
+ 
+std::ostream & HepBoostY::print( std::ostream & os ) const {
+  os << "Boost in Y direction (beta = " << beta_ 
+			<< ", gamma = " << gamma_ << ") ";
+  return os;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/BoostZ.cc
===================================================================
--- trunk/CLHEP/src/BoostZ.cc	(revision 4)
+++ trunk/CLHEP/src/BoostZ.cc	(revision 4)
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepBoostZ class.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/BoostZ.h"
+#include "CLHEP/Vector/Boost.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+HepBoostZ & HepBoostZ::set (double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to set HepBoostZ represents speed >= c."));
+    beta_  = 1.0 - 1.0E-8;              // NaN-proofing
+    gamma_ = 1.0 / sqrt(1.0 - b2);
+    return *this;
+  }    
+  beta_  = beta;
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+  return *this;
+}
+
+// ----------  Accessors:
+
+HepRep4x4 HepBoostZ::rep4x4() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4(   1,      0,    0,    0,
+		      0,      1,    0,    0,
+                      0,      0,  gamma_, bg, 
+		      0,      0,   bg,  gamma_ );
+}
+
+HepRep4x4Symmetric HepBoostZ::rep4x4Symmetric() const {
+  double bg = beta_*gamma_;
+  return HepRep4x4Symmetric(   1,      0,    0,    0,
+		      		       1,    0,    0,
+                      		           gamma_, bg, 
+		      				  gamma_ );
+}
+
+// ----------  Decomposition:
+
+void HepBoostZ::decompose (HepRotation & rotation, HepBoost & boost) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostZ::decompose (HepAxisAngle & rotation, Hep3Vector & boost) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+void HepBoostZ::decompose (HepBoost & boost, HepRotation & rotation) const {
+  HepAxisAngle vdelta = HepAxisAngle();
+  rotation = HepRotation(vdelta);
+  Hep3Vector beta = boostVector();
+  boost = HepBoost(beta);
+}
+
+void HepBoostZ::decompose (Hep3Vector & boost, HepAxisAngle & rotation) const {
+  rotation = HepAxisAngle();
+  boost = boostVector();
+}
+
+// ----------  Comparisons:
+
+double HepBoostZ::distance2( const HepBoost & b ) const {
+  return b.distance2(*this);
+}
+
+double HepBoostZ::distance2( const HepRotation & r ) const {
+  double db2 = norm2();
+  double dr2  = r.norm2();
+  return (db2 + dr2);
+}
+
+double HepBoostZ::distance2( const HepLorentzRotation & lt ) const {
+  HepBoost b1;
+  HepRotation r1;
+  lt.decompose(b1,r1);
+  double db2 = distance2(b1);
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+bool HepBoostZ::isNear (const HepRotation & r, double epsilon) const {
+  double db2 = norm2();
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r.norm2();
+  return (db2+dr2 <= epsilon*epsilon);
+}
+
+bool HepBoostZ::isNear ( const HepLorentzRotation & lt, 
+					double epsilon  ) const {
+  HepBoost b1;
+  HepRotation r1;
+  double db2 = distance2(b1);
+  lt.decompose(b1,r1);
+  if (db2 > epsilon*epsilon) return false;
+  double dr2  = r1.norm2();
+  return (db2 + dr2);
+}
+
+// ----------  Properties:
+
+void HepBoostZ::rectify() {
+  // Assuming the representation of this is close to a true pure boost,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" pure BoostZ matrix for again.
+  
+  double b2 = beta_*beta_;
+  if (b2 >= 1) {
+    beta_ = 1.0 - 1.0e-8;			// NaN-proofing
+    b2 = beta_*beta_;
+  } 
+  gamma_ = 1.0 / sqrt(1.0 - b2);
+}
+
+// ---------- Application:
+
+// ---------- Operations in the group of 4-Rotations
+
+HepBoostZ HepBoostZ::operator * (const HepBoostZ & b) const {
+  return HepBoostZ ( (beta()+b.beta()) / (1+beta()*b.beta()) );
+}
+HepLorentzRotation HepBoostZ::operator * (const HepBoost & b) const {
+  HepLorentzRotation me (*this);
+  return me*b;
+}
+HepLorentzRotation HepBoostZ::operator * (const HepRotation & r) const {
+  HepLorentzRotation me (*this);
+  return me*r;
+}
+HepLorentzRotation HepBoostZ::operator * (const HepLorentzRotation & lt) const {
+  HepLorentzRotation me (*this);
+  return me*lt;
+}
+ 
+// ---------- I/O
+ 
+std::ostream & HepBoostZ::print( std::ostream & os ) const {
+  os << "Boost in Z direction (beta = " << beta_ 
+			<< ", gamma = " << gamma_ << ") ";
+  return os;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/EulerAngles.cc
===================================================================
--- trunk/CLHEP/src/EulerAngles.cc	(revision 4)
+++ trunk/CLHEP/src/EulerAngles.cc	(revision 4)
@@ -0,0 +1,121 @@
+// ----------------------------------------------------------------------
+//
+// EulerAngles.cc
+//
+// Methods for classes, and instances of globals, declared in EulerAngles.h
+//
+// History:
+//
+// 04-Dec-1997	MF	Stub with just PI
+// 12-Jan-1998  WEB	PI now found in ZMutility; used ZMutility headers
+//			where available
+// 16-Mar-1998  WEB	Corrected ZMpvEulerAnglesRep
+// 15-Jun-1998  WEB	Added namespace support
+// 26-Jul-2000  MF	CLHEP version
+// 12-Apr-2001  MF  	NaN-proofing
+// 19-Nov-2001  MF  	Correction to ZMpvEulerAnglesRep, which was affecting
+//			.isNear().  array[3] had been incorrect.
+//			Note - the correct form was used in all other places 
+//			including Rotation.set(phi, theta, psi).
+//
+// ----------------------------------------------------------------------
+
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/EulerAngles.h"
+
+#include "CLHEP/Vector/ThreeVector.h"
+
+#include <iostream>
+
+namespace CLHEP  {
+
+//-*************
+// static consts
+//-*************
+
+double HepEulerAngles::tolerance = Hep3Vector::ToleranceTicks * 1.0e-8;
+
+//-*******************
+// measure of distance
+//-*******************
+
+
+static void ZMpvEulerAnglesRep ( const HepEulerAngles & ex, double array[] ) {
+
+  register double sinPhi   = sin( ex.phi() )  , cosPhi   = cos( ex.phi() );
+  register double sinTheta = sin( ex.theta() ), cosTheta = cos( ex.theta() );
+  register double sinPsi   = sin( ex.psi() )  , cosPsi   = cos( ex.psi() );
+
+  array[0] =   cosPsi * cosPhi   - sinPsi * cosTheta * sinPhi;
+  array[1] =   cosPsi * sinPhi   + sinPsi * cosTheta * cosPhi;
+  array[2] =   sinPsi * sinTheta;
+
+  array[3] = - sinPsi * cosPhi - cosPsi * cosTheta * sinPhi;
+  array[4] = - sinPsi * sinPhi   + cosPsi * cosTheta * cosPhi;
+  array[5] =   cosPsi * sinTheta;
+
+  array[6] =   sinTheta * sinPhi;
+  array[7] = - sinTheta * cosPhi;
+  array[8] =   cosTheta;
+
+} // ZMpvEulerAnglesRep
+
+
+double HepEulerAngles::distance( const EA & ex ) const  {
+
+  double thisRep[9];
+  double exRep[9];
+
+  ZMpvEulerAnglesRep ( *this, thisRep );
+  ZMpvEulerAnglesRep ( ex,    exRep );
+
+  double sum = 0.0;
+  for (int i = 0; i < 9; i++)  {
+    sum += thisRep[i] * exRep[i];
+  }
+
+  double d = 3.0 - sum;		// NaN-proofing: 
+  return  (d >= 0) ? d : 0;		// sqrt(distance) is used in howNear()
+
+}  // HepEulerAngles::distance()
+
+
+bool HepEulerAngles::isNear( const EA & ex, double epsilon ) const  {
+
+  return  distance( ex ) <= epsilon*epsilon ;
+
+}  // HepEulerAngles::isNear()
+
+
+double HepEulerAngles::howNear( const EA & ex ) const  {
+
+  return  sqrt( distance( ex ) );
+
+}  // HepEulerAngles::howNear()
+
+//-**************
+// Global Methods
+//-**************
+
+std::ostream & operator<<(std::ostream & os, const HepEulerAngles & ea)
+{
+  os << "(" << ea.phi() << ", " << ea.theta() << ", " << ea.psi() << ")";
+  return  os;
+}  // operator<<()
+
+void ZMinput3doubles ( std::istream & is, const char * type,
+                       double & x, double & y, double & z );
+
+std::istream & operator>>(std::istream & is, HepEulerAngles & ea) {
+  double thePhi;
+  double theTheta;
+  double thePsi;
+  ZMinput3doubles ( is, "HepEulerAngle", thePhi , theTheta , thePsi );
+  ea.set ( thePhi , theTheta , thePsi );
+  return  is;
+}  // operator>>()
+
+}  // namespace CLHEP
+
+
Index: trunk/CLHEP/src/LorentzRotation.cc
===================================================================
--- trunk/CLHEP/src/LorentzRotation.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzRotation.cc	(revision 4)
@@ -0,0 +1,293 @@
+// -*- C++ -*-
+// $Id: LorentzRotation.cc,v 1.1 2008-06-04 14:15:05 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation basic parts of the HepLorentzRotation class.
+//
+// Some ZOOM methods involving construction from columns and decomposition 
+// into boost*rotation are split off into LorentzRotationC and LorentzRotationD
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <iostream>
+#include <iomanip>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+
+HepLorentzRotation & HepLorentzRotation::set
+				(double bx, double by, double bz) {
+  double bp2 = bx*bx + by*by + bz*bz;
+  if (bp2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Boost Vector supplied to set HepLorentzRotation represents speed >= c."));
+  }    
+  double gamma = 1.0 / sqrt(1.0 - bp2);
+  double bgamma = gamma * gamma / (1.0 + gamma);
+  mxx = 1.0 + bgamma * bx * bx;
+  myy = 1.0 + bgamma * by * by;
+  mzz = 1.0 + bgamma * bz * bz;
+  mxy = myx = bgamma * bx * by;
+  mxz = mzx = bgamma * bx * bz;
+  myz = mzy = bgamma * by * bz;
+  mxt = mtx = gamma * bx;
+  myt = mty = gamma * by;
+  mzt = mtz = gamma * bz;
+  mtt = gamma;
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::set 
+		(const HepBoost & B, const HepRotation & R) {
+  set (B.rep4x4());
+  *this = matrixMultiplication ( R.rep4x4() );
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::set 
+		(const HepRotation & R, const HepBoost & B) {
+  set (R.rep4x4());
+  *this = matrixMultiplication ( B.rep4x4() );
+  return *this;
+}
+
+// ----------  Accessors:
+
+// ------------  Subscripting:
+
+double HepLorentzRotation::operator () (int i, int j) const {
+  if (i == 0) {
+    if (j == 0) { return xx(); }
+    if (j == 1) { return xy(); }
+    if (j == 2) { return xz(); } 
+    if (j == 3) { return xt(); } 
+  } else if (i == 1) {
+    if (j == 0) { return yx(); }
+    if (j == 1) { return yy(); }
+    if (j == 2) { return yz(); } 
+    if (j == 3) { return yt(); } 
+  } else if (i == 2) {
+    if (j == 0) { return zx(); }
+    if (j == 1) { return zy(); }
+    if (j == 2) { return zz(); } 
+    if (j == 3) { return zt(); } 
+  } else if (i == 3) {
+    if (j == 0) { return tx(); }
+    if (j == 1) { return ty(); }
+    if (j == 2) { return tz(); } 
+    if (j == 3) { return tt(); } 
+  } 
+  std::cerr << "HepLorentzRotation subscripting: bad indeces "
+	    << "(" << i << "," << j << ")\n";
+  return 0.0;
+} 
+
+// ---------- Application:
+
+
+// ---------- Comparison:
+
+int HepLorentzRotation::compare( const HepLorentzRotation & m  ) const {
+       if (mtt<m.mtt) return -1; else if (mtt>m.mtt) return 1;
+  else if (mtz<m.mtz) return -1; else if (mtz>m.mtz) return 1;
+  else if (mty<m.mty) return -1; else if (mty>m.mty) return 1;
+  else if (mtx<m.mtx) return -1; else if (mtx>m.mtx) return 1;
+
+  else if (mzt<m.mzt) return -1; else if (mzt>m.mzt) return 1;
+  else if (mzz<m.mzz) return -1; else if (mzz>m.mzz) return 1;
+  else if (mzy<m.mzy) return -1; else if (mzy>m.mzy) return 1;
+  else if (mzx<m.mzx) return -1; else if (mzx>m.mzx) return 1;
+
+  else if (myt<m.myt) return -1; else if (myt>m.myt) return 1;
+  else if (myz<m.myz) return -1; else if (myz>m.myz) return 1;
+  else if (myy<m.myy) return -1; else if (myy>m.myy) return 1;
+  else if (myx<m.myx) return -1; else if (myx>m.myx) return 1;
+
+  else if (mxt<m.mxt) return -1; else if (mxt>m.mxt) return 1;
+  else if (mxz<m.mxz) return -1; else if (mxz>m.mxz) return 1;
+  else if (mxy<m.mxy) return -1; else if (mxy>m.mxy) return 1;
+  else if (mxx<m.mxx) return -1; else if (mxx>m.mxx) return 1;
+
+  else return 0;
+}
+
+
+// ---------- Operations in the group of 4-Rotations
+
+HepLorentzRotation
+HepLorentzRotation::matrixMultiplication(const HepRep4x4 & m) const {
+  return HepLorentzRotation(
+    mxx*m.xx_ + mxy*m.yx_ + mxz*m.zx_ + mxt*m.tx_,
+    mxx*m.xy_ + mxy*m.yy_ + mxz*m.zy_ + mxt*m.ty_,
+    mxx*m.xz_ + mxy*m.yz_ + mxz*m.zz_ + mxt*m.tz_,
+    mxx*m.xt_ + mxy*m.yt_ + mxz*m.zt_ + mxt*m.tt_,
+
+    myx*m.xx_ + myy*m.yx_ + myz*m.zx_ + myt*m.tx_,
+    myx*m.xy_ + myy*m.yy_ + myz*m.zy_ + myt*m.ty_,
+    myx*m.xz_ + myy*m.yz_ + myz*m.zz_ + myt*m.tz_,
+    myx*m.xt_ + myy*m.yt_ + myz*m.zt_ + myt*m.tt_,
+
+    mzx*m.xx_ + mzy*m.yx_ + mzz*m.zx_ + mzt*m.tx_,
+    mzx*m.xy_ + mzy*m.yy_ + mzz*m.zy_ + mzt*m.ty_,
+    mzx*m.xz_ + mzy*m.yz_ + mzz*m.zz_ + mzt*m.tz_,
+    mzx*m.xt_ + mzy*m.yt_ + mzz*m.zt_ + mzt*m.tt_,
+
+    mtx*m.xx_ + mty*m.yx_ + mtz*m.zx_ + mtt*m.tx_,
+    mtx*m.xy_ + mty*m.yy_ + mtz*m.zy_ + mtt*m.ty_,
+    mtx*m.xz_ + mty*m.yz_ + mtz*m.zz_ + mtt*m.tz_,
+    mtx*m.xt_ + mty*m.yt_ + mtz*m.zt_ + mtt*m.tt_ );
+}
+
+HepLorentzRotation & HepLorentzRotation::rotateX(double delta) {
+  double c = cos (delta);
+  double s = sin (delta);
+  HepLorentzVector rowy = row2();
+  HepLorentzVector rowz = row3();
+  HepLorentzVector r2 = c * rowy - s * rowz;
+  HepLorentzVector r3 = s * rowy + c * rowz;
+  myx = r2.x();   myy = r2.y();   myz = r2.z();   myt = r2.t();	
+  mzx = r3.x();   mzy = r3.y();   mzz = r3.z();   mzt = r3.t();	
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::rotateY(double delta) {
+  double c = cos (delta);
+  double s = sin (delta);
+  HepLorentzVector rowx = row1();
+  HepLorentzVector rowz = row3();
+  HepLorentzVector r1 =  c * rowx + s * rowz;
+  HepLorentzVector r3 = -s * rowx + c * rowz;
+  mxx = r1.x();   mxy = r1.y();   mxz = r1.z();   mxt = r1.t();	
+  mzx = r3.x();   mzy = r3.y();   mzz = r3.z();   mzt = r3.t();	
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::rotateZ(double delta) {
+  double c = cos (delta);
+  double s = sin (delta);
+  HepLorentzVector rowx = row1();
+  HepLorentzVector rowy = row2();
+  HepLorentzVector r1 = c * rowx - s * rowy;
+  HepLorentzVector r2 = s * rowx + c * rowy;
+  mxx = r1.x();   mxy = r1.y();   mxz = r1.z();   mxt = r1.t();
+  myx = r2.x();   myy = r2.y();   myz = r2.z();   myt = r2.t();
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::boostX(double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to HepLorentzRotation::boostX represents speed >= c."));
+  }    
+  double g  = 1.0/sqrt(1.0-b2);
+  double bg = beta*g;
+  HepLorentzVector rowx = row1();
+  HepLorentzVector rowt = row4();
+  HepLorentzVector r1 =  g * rowx + bg * rowt;
+  HepLorentzVector r4 = bg * rowx +  g * rowt;
+  mxx = r1.x();   mxy = r1.y();   mxz = r1.z();   mxt = r1.t();	
+  mtx = r4.x();   mty = r4.y();   mtz = r4.z();   mtt = r4.t();	
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::boostY(double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to HepLorentzRotation::boostY represents speed >= c."));
+  }    
+  double g  = 1.0/sqrt(1.0-b2);
+  double bg = beta*g;
+  HepLorentzVector rowy = row2();
+  HepLorentzVector rowt = row4();
+  HepLorentzVector r2 =  g * rowy + bg * rowt;
+  HepLorentzVector r4 = bg * rowy +  g * rowt;
+  myx = r2.x();   myy = r2.y();   myz = r2.z();   myt = r2.t();	
+  mtx = r4.x();   mty = r4.y();   mtz = r4.z();   mtt = r4.t();	
+  return *this;
+}
+
+HepLorentzRotation & HepLorentzRotation::boostZ(double beta) {
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+    "Beta supplied to HepLorentzRotation::boostZ represents speed >= c."));
+  }    
+  double g  = 1.0/sqrt(1.0-b2);
+  double bg = beta*g;
+  HepLorentzVector rowz = row3();
+  HepLorentzVector rowt = row4();
+  HepLorentzVector r3 =  g * rowz + bg * rowt;
+  HepLorentzVector r4 = bg * rowz +  g * rowt;
+  mtx = r4.x();   mty = r4.y();   mtz = r4.z();   mtt = r4.t();	
+  mzx = r3.x();   mzy = r3.y();   mzz = r3.z();   mzt = r3.t();	
+  return *this;
+}
+
+std::ostream & HepLorentzRotation::print( std::ostream & os ) const {
+//  using std::setw;
+//  using std::setprecision;
+  os << "\n   [ ( " <<
+        std::setw(11) << std::setprecision(6) << xx() << "   " <<
+        std::setw(11) << std::setprecision(6) << xy() << "   " <<
+        std::setw(11) << std::setprecision(6) << xz() << "   " <<
+        std::setw(11) << std::setprecision(6) << xt() << ")\n"
+     << "     ( " <<
+        std::setw(11) << std::setprecision(6) << yx() << "   " <<
+        std::setw(11) << std::setprecision(6) << yy() << "   " <<
+        std::setw(11) << std::setprecision(6) << yz() << "   " <<
+        std::setw(11) << std::setprecision(6) << yt() << ")\n"
+     << "     ( " <<
+        std::setw(11) << std::setprecision(6) << zx() << "   " <<
+        std::setw(11) << std::setprecision(6) << zy() << "   " <<
+        std::setw(11) << std::setprecision(6) << zz() << "   " <<
+        std::setw(11) << std::setprecision(6) << zt() << ")\n"
+     << "     ( " <<
+        std::setw(11) << std::setprecision(6) << tx() << "   " <<
+        std::setw(11) << std::setprecision(6) << ty() << "   " <<
+        std::setw(11) << std::setprecision(6) << tz() << "   " <<
+        std::setw(11) << std::setprecision(6) << tt() << ") ]\n";
+  return os;
+}
+
+HepLorentzRotation operator* ( const HepRotation & r,
+                               const HepLorentzRotation & lt) {
+  r.rep4x4();
+  lt.rep4x4();
+  return HepLorentzRotation( HepRep4x4(
+         r.xx()*lt.xx() + r.xy()*lt.yx() + r.xz()*lt.zx() + r.xt()*lt.tx(),
+	 r.xx()*lt.xy() + r.xy()*lt.yy() + r.xz()*lt.zy() + r.xt()*lt.ty(),
+	 r.xx()*lt.xz() + r.xy()*lt.yz() + r.xz()*lt.zz() + r.xt()*lt.tz(),
+	 r.xx()*lt.xt() + r.xy()*lt.yt() + r.xz()*lt.zt() + r.xt()*lt.tt(),
+
+         r.yx()*lt.xx() + r.yy()*lt.yx() + r.yz()*lt.zx() + r.yt()*lt.tx(),
+         r.yx()*lt.xy() + r.yy()*lt.yy() + r.yz()*lt.zy() + r.yt()*lt.ty(),
+         r.yx()*lt.xz() + r.yy()*lt.yz() + r.yz()*lt.zz() + r.yt()*lt.tz(),
+         r.yx()*lt.xt() + r.yy()*lt.yt() + r.yz()*lt.zt() + r.yt()*lt.tt(),
+
+         r.zx()*lt.xx() + r.zy()*lt.yx() + r.zz()*lt.zx() + r.zt()*lt.tx(),
+         r.zx()*lt.xy() + r.zy()*lt.yy() + r.zz()*lt.zy() + r.zt()*lt.ty(),
+         r.zx()*lt.xz() + r.zy()*lt.yz() + r.zz()*lt.zz() + r.zt()*lt.tz(),
+         r.zx()*lt.xt() + r.zy()*lt.yt() + r.zz()*lt.zt() + r.zt()*lt.tt(),
+
+         r.tx()*lt.xx() + r.ty()*lt.yx() + r.tz()*lt.zx() + r.tt()*lt.tx(),
+         r.tx()*lt.xy() + r.ty()*lt.yy() + r.tz()*lt.zy() + r.tt()*lt.ty(),
+         r.tx()*lt.xz() + r.ty()*lt.yz() + r.tz()*lt.zz() + r.tt()*lt.tz(),
+         r.tx()*lt.xt() + r.ty()*lt.yt() + r.tz()*lt.zt() + r.tt()*lt.tt() ) );
+}
+
+
+const HepLorentzRotation HepLorentzRotation::IDENTITY;
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzRotationC.cc
===================================================================
--- trunk/CLHEP/src/LorentzRotationC.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzRotationC.cc	(revision 4)
@@ -0,0 +1,210 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of that part of the HepLorentzRotation class
+// which is concerned with setting or constructing the transformation based 
+// on 4 supplied columns or rows.
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+HepLorentzRotation & HepLorentzRotation::set (const HepLorentzVector & col1,
+                       			      const HepLorentzVector & col2,
+			                      const HepLorentzVector & col3,
+			                      const HepLorentzVector & col4) {
+  // First, test that the four cols do represent something close to a
+  // true LT:
+
+  ZMpvMetric_t savedMetric = HepLorentzVector::setMetric (TimePositive);
+
+  if ( col4.getT() < 0 ) {
+      ZMthrowC (ZMxpvImproperTransformation(
+     "column 4 supplied to define transformation has negative T component"));
+    *this = HepLorentzRotation();
+    return *this;
+  }
+
+  double u1u1 = col1.dot(col1);
+  double f11  = fabs(u1u1 + 1.0);
+  if ( f11 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotSymplectic(
+      "column 1 supplied for HepLorentzRotation has w*w != -1"));
+  }
+  double u2u2 = col2.dot(col2);
+  double f22  = fabs(u2u2 + 1.0);
+  if ( f22 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotSymplectic(
+      "column 2 supplied for HepLorentzRotation has w*w != -1"));
+  }
+  double u3u3 = col3.dot(col3);
+  double f33  = fabs(u3u3 + 1.0);
+  if ( f33 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotSymplectic(
+      "column 3 supplied for HepLorentzRotation has w*w != -1"));
+  }
+  double u4u4 = col4.dot(col4);
+  double f44  = fabs(u4u4 - 1.0);
+  if ( f44 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotSymplectic(
+      "column 4 supplied for HepLorentzRotation has w*w != +1"));
+  }
+
+  double u1u2 = col1.dot(col2);
+  double f12  = fabs(u1u2);
+  if ( f12 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 1 and 2 supplied for HepLorentzRotation have non-zero dot"));
+  }
+  double u1u3 = col1.dot(col3);
+  double f13  = fabs(u1u3);
+
+  if ( f13 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 1 and 3 supplied for HepLorentzRotation have non-zero dot"));
+  }
+  double u1u4 = col1.dot(col4);
+  double f14  = fabs(u1u4);
+  if ( f14 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 1 and 4 supplied for HepLorentzRotation have non-zero dot"));
+  }
+  double u2u3 = col2.dot(col3);
+  double f23  = fabs(u2u3);
+  if ( f23 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 2 and 3 supplied for HepLorentzRotation have non-zero dot"));
+  }
+  double u2u4 = col2.dot(col4);
+  double f24  = fabs(u2u4);
+  if ( f24 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 2 and 4 supplied for HepLorentzRotation have non-zero dot"));
+  }
+  double u3u4 = col3.dot(col4);
+  double f34  = fabs(u3u4);
+  if ( f34 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+   "columns 3 and 4 supplied for HepLorentzRotation have non-zero dot"));
+  }
+
+  // Our strategy will be to order the cols, then do gram-schmidt on them
+  // (that is, remove the components of col d that make it non-orthogonal to
+  // col c, normalize that, then remove the components of b that make it
+  // non-orthogonal to d and to c, normalize that, etc.
+
+  // Because col4, the time col, is most likely to be computed directly, we
+  // will start from there and work left-ward.
+
+  HepLorentzVector a, b, c, d;
+  bool isLorentzTransformation = true;
+  double norm;
+
+  d = col4;
+  norm = d.dot(d);
+  if (norm <= 0.0) {
+    isLorentzTransformation = false;
+    if (norm == 0.0) {
+      d = T_HAT4;       // Moot, but let's keep going...
+
+      norm = 1.0;
+    }
+  }
+  d /= norm;
+
+  c = col3 - col3.dot(d) * d;
+  norm = -c.dot(c);
+  if (norm <= 0.0) {
+    isLorentzTransformation = false;
+    if (norm == 0.0) {
+      c = Z_HAT4;       // Moot
+      norm = 1.0;
+    }
+  }
+  c /= norm;
+
+  b = col2 + col2.dot(c) * c - col2.dot(d) * d;
+  norm = -b.dot(b);
+  if (norm <= 0.0) {
+    isLorentzTransformation = false;
+    if (norm == 0.0) {
+      b = Y_HAT4;       // Moot
+      norm = 1.0;
+    }
+  }
+  b /= norm;
+
+  a = col1 + col1.dot(b) * b + col1.dot(c) * c - col1.dot(d) * d;
+  norm = -a.dot(a);
+  if (norm <= 0.0) {
+    isLorentzTransformation = false;
+    if (norm == 0.0) {
+      a = X_HAT4;       // Moot
+      norm = 1.0;
+    }
+  }
+  a /= norm;
+
+  if ( !isLorentzTransformation ) {
+      ZMthrowC (ZMxpvImproperTransformation(
+        "cols 1-4 supplied to define transformation form either \n"
+        "       a boosted reflection or a tachyonic transformation -- \n"
+        "       transformation will be set to Identity "));
+
+
+    *this = HepLorentzRotation();
+  }
+
+  if ( isLorentzTransformation ) {
+    mxx = a.x(); myx = a.y(); mzx = a.z(); mtx = a.t();
+    mxy = b.x(); myy = b.y(); mzy = b.z(); mty = b.t();
+    mxz = c.x(); myz = c.y(); mzz = c.z(); mtz = c.t();
+    mxt = d.x(); myt = d.y(); mzt = d.z(); mtt = d.t();
+  }
+
+  HepLorentzVector::setMetric (savedMetric);
+  return *this;
+
+} // set ( col1, col2, col3, col4 )
+
+HepLorentzRotation & HepLorentzRotation::setRows
+	 (const HepLorentzVector & row1,
+          const HepLorentzVector & row2,
+	  const HepLorentzVector & row3,
+	  const HepLorentzVector & row4) {
+  // Set based on using those rows as columns:
+  set (row1, row2, row3, row4);
+  // Now transpose in place:
+  register double q1, q2, q3;
+  q1  = mxy;  q2  = mxz;  q3  = mxt;
+  mxy = myx;  mxz = mzx;  mxt = mtx;
+  myx = q1;   mzx = q2;   mtx = q3;
+  q1  = myz;  q2  = myt;  q3  = mzt;
+  myz = mzy;  myt = mty;  mzt = mtz;
+  mzy = q1;   mty = q2;   mtz = q3;
+  return *this;
+} // LorentzTransformation::setRows(row1 ... row4)
+
+HepLorentzRotation::HepLorentzRotation ( const HepLorentzVector & col1,
+		                         const HepLorentzVector & col2,
+                		         const HepLorentzVector & col3,
+                       			 const HepLorentzVector & col4 ) 
+{
+  set ( col1, col2, col3, col4 );
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/LorentzRotationD.cc
===================================================================
--- trunk/CLHEP/src/LorentzRotationD.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzRotationD.cc	(revision 4)
@@ -0,0 +1,212 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of those parts of the HepLorentzRotation class
+// which involve decomposition into Boost*Rotation.
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+
+namespace CLHEP  {
+
+// ----------  Decomposition:
+
+void HepLorentzRotation::decompose 
+	(HepBoost & boost, HepRotation & rotation) const {
+
+  // The boost will be the pure boost based on column 4 of the transformation
+  // matrix.  Since the constructor takes the beta vector, and not beta*gamma,
+  // we first divide through by gamma = the tt element.  This of course can
+  // never be zero since the last row has t**2 - v**2 = +1.
+
+  Hep3Vector betaVec ( xt(), yt(), zt() );
+  betaVec *= 1.0 / tt();
+  boost.set( betaVec );
+
+  // The rotation will be inverse of B times T.
+
+  HepBoost B( -betaVec );
+  HepLorentzRotation R( B * *this );
+
+  HepRep3x3 m3  ( R.xx(), R.xy(), R.xz(),
+                  R.yx(), R.yy(), R.yz(),
+                  R.zx(), R.zy(), R.zz() );
+  rotation.set( m3 );
+  rotation.rectify();
+  
+  return;
+
+}
+
+void HepLorentzRotation::decompose 
+	(Hep3Vector & boost, HepAxisAngle & rotation) const {
+  HepRotation r;
+  HepBoost b;
+  decompose(b,r);
+  boost = b.boostVector();
+  rotation = r.axisAngle();
+  return;
+}
+
+void HepLorentzRotation::decompose 
+	(HepRotation & rotation, HepBoost & boost) const {
+
+  // In this case the pure boost is based on row 4 of the matrix.  
+
+  Hep3Vector betaVec( tx(), ty(), tz() );
+  betaVec *= 1.0 / tt();
+  boost.set( betaVec );
+
+  // The rotation will be T times the inverse of B.
+
+  HepBoost B( -betaVec );
+  HepLorentzRotation R( *this * B );
+
+  HepRep3x3 m3 ( R.xx(), R.xy(), R.xz(),
+                 R.yx(), R.yy(), R.yz(),
+                 R.zx(), R.zy(), R.zz() );
+  rotation.set( m3 );
+  rotation.rectify();
+  return;
+
+}
+
+void HepLorentzRotation::decompose 
+	(HepAxisAngle & rotation, Hep3Vector & boost) const {
+  HepRotation r;
+  HepBoost b;
+  decompose(r,b);
+  rotation = r.axisAngle();
+  boost = b.boostVector();
+  return;
+}
+
+double HepLorentzRotation::distance2( const HepBoost & b ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  double db2 = b1.distance2( b );
+  double dr2 = r1.norm2(); 
+  return ( db2 + dr2 );
+}
+
+double HepLorentzRotation::distance2( const HepRotation & r ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  double db2 = b1.norm2( );
+  double dr2 = r1.distance2( r ); 
+  return ( db2 + dr2 );
+}
+
+double HepLorentzRotation::distance2( 
+				   const HepLorentzRotation & lt  ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  HepBoost    b2;
+  HepRotation r2; 
+  lt.decompose (b2, r2);
+  double db2 = b1.distance2( b2 );
+  double dr2 = r1.distance2( r2 ); 
+  return ( db2 + dr2 );
+}
+
+double HepLorentzRotation::howNear( const HepBoost & b ) const {
+  return sqrt( distance2( b ) );
+}
+double HepLorentzRotation::howNear( const HepRotation & r ) const {
+  return sqrt( distance2( r ) );
+}
+double HepLorentzRotation::howNear( const HepLorentzRotation & lt )const {
+  return sqrt( distance2( lt ) );
+}
+
+bool HepLorentzRotation::isNear(
+		const HepBoost & b, double epsilon ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  double db2 = b1.distance2(b);
+  if ( db2 > epsilon*epsilon ) {
+     return false;       // Saves the time-consuming Rotation::norm2
+  }
+  double dr2 = r1.norm2();
+  return ( (db2 + dr2) <= epsilon*epsilon );
+}
+
+bool HepLorentzRotation::isNear(
+		const HepRotation & r, double epsilon ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  double db2 = b1.norm2();
+  if ( db2 > epsilon*epsilon ) {
+     return false;       // Saves the time-consuming Rotation::distance2
+  }
+  double dr2 = r1.distance2(r);
+  return ( (db2 + dr2) <= epsilon*epsilon );
+}
+
+bool HepLorentzRotation::isNear(
+		const HepLorentzRotation & lt, double epsilon ) const {
+  HepBoost    b1;
+  HepRotation r1; 
+  decompose( b1, r1 );
+  HepBoost    b2;
+  HepRotation r2; 
+  lt.decompose (b2, r2);
+  double db2 = b1.distance2(b2);
+  if ( db2 > epsilon*epsilon ) {
+     return false;       // Saves the time-consuming Rotation::distance2
+  }
+  double dr2 = r1.distance2(r2);
+  return ( (db2 + dr2) <= epsilon*epsilon );
+}
+
+double HepLorentzRotation::norm2() const {
+  HepBoost    b;
+  HepRotation r;
+  decompose( b, r );
+  return b.norm2() + r.norm2();
+}
+
+void HepLorentzRotation::rectify() {
+  
+  // Assuming the representation of this is close to a true LT,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" orthosymplectic matrix for the LT again.
+ 
+  // There are several ways to do this, all equivalent to lowest order in
+  // the corrected error.  We choose to form an LT based on the inverse boost
+  // extracted from row 4, and left-multiply by LT to form what would be
+  // a rotation if the LT were kosher.  We drop the possibly non-zero t
+  // components of that, rectify that rotation and multiply back by the boost.
+                    
+  Hep3Vector beta (tx(), ty(), tz());
+  double gam = tt();			// NaN-proofing
+  if ( gam <= 0 ) {
+    ZMthrowA ( ZMxpvImproperTransformation (
+	"rectify() on a transformation with tt() <= 0 - will not help!" ));
+    gam = 1;
+  }
+  beta *= 1.0/gam;
+  HepLorentzRotation R = (*this) * HepBoost(-beta);
+
+  HepRep3x3  m3 ( R.xx(), R.xy(), R.xz(),
+                  R.yx(), R.yy(), R.yz(),
+                  R.zx(), R.zy(), R.zz() );
+
+  HepRotation Rgood (m3);
+  Rgood.rectify();
+
+  set ( Rgood, HepBoost(beta) );
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzVector.cc
===================================================================
--- trunk/CLHEP/src/LorentzVector.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVector.cc	(revision 4)
@@ -0,0 +1,251 @@
+// -*- C++ -*-
+// $Id: LorentzVector.cc,v 1.1 2008-06-04 14:15:06 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of that portion of the HepLorentzVector class
+// which was in the original CLHEP and which does not force loading of either
+// Rotation.cc or LorentzRotation.cc
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <iostream>
+
+namespace CLHEP  {
+
+double HepLorentzVector::operator () (int i) const {
+  switch(i) {
+  case X:
+  case Y:
+  case Z:
+    return pp(i);
+  case T:
+    return e();
+  default:
+    std::cerr << "HepLorentzVector subscripting: bad index (" << i << ")"
+		 << std::endl;
+  }
+  return 0.;
+}  
+
+double & HepLorentzVector::operator () (int i) {
+  static double dummy;
+  switch(i) {
+  case X:
+  case Y:
+  case Z:
+    return pp(i);
+  case T:
+    return ee;
+  default:
+    std::cerr
+      << "HepLorentzVector subscripting: bad index (" << i << ")"
+      << std::endl;
+    return dummy;
+  }
+}
+
+HepLorentzVector & HepLorentzVector::boost
+				(double bx, double by, double bz){
+  double b2 = bx*bx + by*by + bz*bz;
+  register double gamma = 1.0 / sqrt(1.0 - b2);
+  register double bp = bx*x() + by*y() + bz*z();
+  register double gamma2 = b2 > 0 ? (gamma - 1.0)/b2 : 0.0;
+
+  setX(x() + gamma2*bp*bx + gamma*bx*t());
+  setY(y() + gamma2*bp*by + gamma*by*t());
+  setZ(z() + gamma2*bp*bz + gamma*bz*t());
+  setT(gamma*(t() + bp));
+  return *this;
+}
+
+HepLorentzVector & HepLorentzVector::rotateX(double a) {
+  pp.rotateX(a); 
+  return *this; 
+}
+HepLorentzVector & HepLorentzVector::rotateY(double a) { 
+  pp.rotateY(a); 
+  return *this; 
+}
+HepLorentzVector & HepLorentzVector::rotateZ(double a) { 
+  pp.rotateZ(a); 
+  return *this; 
+}
+
+HepLorentzVector & HepLorentzVector::rotateUz(const Hep3Vector &v) {
+  pp.rotateUz(v);
+  return *this;
+}
+
+std::ostream & operator<< (std::ostream & os, const HepLorentzVector & v)
+{
+  return os << "(" << v.x() << "," << v.y() << "," << v.z()
+	    << ";" << v.t() << ")";
+}
+
+std::istream & operator>> (std::istream & is, HepLorentzVector & v) {
+
+// Required format is ( a, b, c; d ) that is, four numbers, preceded by
+// (, followed by ), components of the spatial vector separated by commas,
+// time component separated by semicolon. The four numbers are taken
+// as x, y, z, t.
+
+  double x, y, z, t;
+  char c;
+
+  is >> std::ws >> c;
+    // ws is defined to invoke eatwhite(istream & )
+    // see (Stroustrup gray book) page 333 and 345.
+  if (is.fail() || c != '(' ) {
+    std::cerr << "Could not find required opening parenthesis "
+	      << "in input of a HepLorentzVector" << std::endl;
+    return is;
+  }
+
+  is >> x >> std::ws >> c;
+  if (is.fail() || c != ',' ) {
+    std::cerr << "Could not find x value and required trailing comma "
+	      << "in input of a HepLorentzVector" << std::endl; 
+    return is;
+  }
+
+  is >> y >> std::ws >> c;
+  if (is.fail() || c != ',' ) {
+    std::cerr << "Could not find y value and required trailing comma "
+              <<  "in input of a HepLorentzVector" << std::endl;
+    return is;
+  }
+
+  is >> z >> std::ws >> c;
+  if (is.fail() || c != ';' ) {
+    std::cerr << "Could not find z value and required trailing semicolon "
+		 <<  "in input of a HepLorentzVector" << std::endl;
+    return is;
+  }
+
+  is >> t >> std::ws >> c;
+  if (is.fail() || c != ')' ) {
+    std::cerr << "Could not find t value and required close parenthesis "
+		 << "in input of a HepLorentzVector" << std::endl;
+    return is;
+  }
+
+  v.setX(x);
+  v.setY(y);
+  v.setZ(z);
+  v.setT(t);
+  return is;
+}
+
+// The following were added when ZOOM classes were merged in:
+
+HepLorentzVector & HepLorentzVector::operator /= (double c) {
+  if (c == 0) {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "Attempt to do LorentzVector /= 0 -- \n"
+      "division by zero would produce infinite or NAN components"));
+  }
+  double oneOverC = 1.0/c;
+  pp *= oneOverC;
+  ee *= oneOverC;
+  return *this;
+} /* w /= c */
+
+HepLorentzVector operator / (const HepLorentzVector & w, double c) {
+if (c == 0) {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "Attempt to do LorentzVector / 0 -- \n"
+      "division by zero would produce infinite or NAN components"));
+  }
+  double oneOverC = 1.0/c;
+  return HepLorentzVector (w.getV() * oneOverC,
+                        w.getT() * oneOverC);
+} /* LV = w / c */
+
+Hep3Vector HepLorentzVector::boostVector() const {
+  if (ee == 0) {
+    if (pp.mag2() == 0) {
+      return Hep3Vector(0,0,0);
+    } else {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "boostVector computed for LorentzVector with t=0 -- infinite result"));
+    return pp/ee;
+    }
+  }
+  if (restMass2() <= 0) {
+    ZMthrowC (ZMxpvTachyonic(
+      "boostVector computed for a non-timelike LorentzVector "));
+        // result will make analytic sense but is physically meaningless
+  }
+  return pp * (1./ee);
+} /* boostVector */
+
+
+HepLorentzVector & HepLorentzVector::boostX (double beta){
+  register double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "boost along X with beta >= 1 (speed of light) -- no boost done"));
+  } else {
+    register double gamma = sqrt(1./(1-b2));
+    register double tt = ee;
+    ee = gamma*(ee + beta*pp.getX());
+    pp.setX(gamma*(pp.getX() + beta*tt));
+  }
+  return *this;
+} /* boostX */
+
+HepLorentzVector & HepLorentzVector::boostY (double beta){
+  register double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "boost along Y with beta >= 1 (speed of light) -- \nno boost done"));
+  } else {
+    register double gamma = sqrt(1./(1-b2));
+    register double tt = ee;
+    ee = gamma*(ee + beta*pp.getY());
+    pp.setY(gamma*(pp.getY() + beta*tt));
+  }
+  return *this;
+} /* boostY */
+
+HepLorentzVector & HepLorentzVector::boostZ (double beta){
+  register double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "boost along Z with beta >= 1 (speed of light) -- \nno boost done"));
+  } else {
+    register double gamma = sqrt(1./(1-b2));
+    register double tt = ee;
+    ee = gamma*(ee + beta*pp.getZ());
+    pp.setZ(gamma*(pp.getZ() + beta*tt));
+  }
+  return *this;
+} /* boostZ */
+
+double HepLorentzVector::setTolerance ( double tol ) {
+// Set the tolerance for two LorentzVectors to be considered near each other
+  double oldTolerance (tolerance);
+  tolerance = tol;
+  return oldTolerance;
+}
+
+double HepLorentzVector::getTolerance ( ) {
+// Get the tolerance for two LorentzVectors to be considered near each other
+  return tolerance;
+}
+
+double HepLorentzVector::tolerance = 
+				Hep3Vector::ToleranceTicks * 2.22045e-16;
+double HepLorentzVector::metric = 1.0;
+
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzVectorB.cc
===================================================================
--- trunk/CLHEP/src/LorentzVectorB.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVectorB.cc	(revision 4)
@@ -0,0 +1,83 @@
+// -*- C++ -*-
+// $Id: LorentzVectorB.cc,v 1.1 2008-06-04 14:15:06 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepLorentzVector class:
+// Those methods originating in ZOOM dealing with simple boosts and rotations.
+// Use of one of these methods will not force loading of the HepRotation or
+// HepLorentzRotation class.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+//-*********
+// rotationOf()
+//-*********
+
+// Each of these is a shell over a rotate method.
+
+HepLorentzVector rotationXOf
+	(const HepLorentzVector & vec, double phi){
+  HepLorentzVector vv (vec);
+  return vv.rotateX (phi);
+}
+
+HepLorentzVector rotationYOf
+	(const HepLorentzVector & vec, double phi){
+  HepLorentzVector vv (vec);
+  return vv.rotateY (phi);
+}
+
+HepLorentzVector rotationZOf
+	(const HepLorentzVector & vec, double phi){
+  HepLorentzVector vv (vec);
+  return vv.rotateZ (phi);
+}
+
+//-********
+// boost
+//-********
+
+HepLorentzVector & HepLorentzVector::boost 
+			( const Hep3Vector & axis,  double beta ) {
+  if (beta==0) {
+    return *this; // do nothing for a 0 boost
+  }
+  double r2 = axis.mag2();
+  if ( r2 == 0 ) {
+    ZMthrowA (ZMxpvZeroVector(
+      "A zero vector used as axis defining a boost -- no boost done"));
+    return *this;
+  } 
+  double b2 = beta*beta;
+  if (b2 >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "LorentzVector boosted with beta >= 1 (speed of light) -- \n"
+      "no boost done"));
+  } else {
+    Hep3Vector u = axis.unit();
+    register double gamma = sqrt(1./(1.-b2));
+    register double betaDotV = u.dot(pp)*beta;
+    register double tt = ee;
+
+    ee = gamma * (tt + betaDotV);
+    pp += ( ((gamma-1)/b2)*betaDotV*beta + gamma*beta*tt ) * u;
+    // Note:  I have verified the behavior of this even when beta is very
+    //        small -- (gamma-1)/b2 becomes inaccurate by O(1), but it is then
+    //        multiplied by O(beta**2) and added to an O(beta) term, so the
+    //        inaccuracy does not affect the final result.
+  }
+  return *this;
+} /* boost (axis, beta) */
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzVectorC.cc
===================================================================
--- trunk/CLHEP/src/LorentzVectorC.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVectorC.cc	(revision 4)
@@ -0,0 +1,260 @@
+// -*- C++ -*-
+// $Id: LorentzVectorC.cc,v 1.1 2008-06-04 14:15:06 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the HepLorentzVector class:
+// Those methods originating with ZOOM dealing with comparison (other than
+// isSpaceLike, isLightlike, isTimelike, which are in the main part.)
+//
+// 11/29/05 mf in deltaR, replaced the direct subtraction 
+// pp.phi() - w.getV().phi() with pp.deltaRPhi(w.getV()) which behaves 
+// correctly across the 2pi boundary.
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+//-***********
+// Comparisons
+//-***********
+
+int HepLorentzVector::compare (const HepLorentzVector & w) const {
+  if       ( ee > w.ee ) {
+    return 1;
+  } else if ( ee < w.ee ) {
+    return -1;
+  } else {
+    return ( pp.compare(w.pp) );
+  }
+} /* Compare */
+
+bool HepLorentzVector::operator > (const HepLorentzVector & w) const {
+        return (compare(w)  > 0);
+}
+bool HepLorentzVector::operator < (const HepLorentzVector & w) const {
+        return (compare(w)  < 0);
+}
+bool HepLorentzVector::operator>= (const HepLorentzVector & w) const {
+        return (compare(w) >= 0);
+}
+bool HepLorentzVector::operator<= (const HepLorentzVector & w) const {
+        return (compare(w) <= 0);
+}
+
+//-********
+// isNear
+// howNear
+//-********
+
+bool HepLorentzVector::isNear(const HepLorentzVector & w, 
+						double epsilon) const {
+  double limit = fabs(pp.dot(w.pp));
+  limit += .25*((ee+w.ee)*(ee+w.ee));
+  limit *= epsilon*epsilon;
+  double delta = (pp - w.pp).mag2();
+  delta +=  (ee-w.ee)*(ee-w.ee);
+  return (delta <= limit );
+} /* isNear() */
+
+double HepLorentzVector::howNear(const HepLorentzVector & w) const {
+  double wdw = fabs(pp.dot(w.pp)) + .25*((ee+w.ee)*(ee+w.ee));
+  double delta = (pp - w.pp).mag2() + (ee-w.ee)*(ee-w.ee);
+  if ( (wdw > 0) && (delta < wdw)  ) {
+    return sqrt (delta/wdw);
+  } else if ( (wdw == 0) && (delta == 0) ) {
+    return 0;
+  } else {
+    return 1;
+  }
+} /* howNear() */
+
+//-*********
+// isNearCM
+// howNearCM
+//-*********
+
+bool HepLorentzVector::isNearCM
+			(const HepLorentzVector & w, double epsilon) const {
+
+  double tTotal = (ee + w.ee);
+  Hep3Vector vTotal (pp + w.pp);
+  double vTotal2 = vTotal.mag2();
+
+  if ( vTotal2 >= tTotal*tTotal ) {
+    // Either one or both vectors are spacelike, or the dominant T components
+    // are in opposite directions.  So boosting and testing makes no sense;
+    // but we do consider two exactly equal vectors to be equal in any frame,
+    // even if they are spacelike and can't be boosted to a CM frame.
+    return (*this == w);
+  }
+
+  if ( vTotal2 == 0 ) {  // no boost needed!
+    return (isNear(w, epsilon));
+  }
+
+  // Find the boost to the CM frame.  We know that the total vector is timelike.
+
+  double tRecip = 1./tTotal;
+  Hep3Vector boost ( vTotal * (-tRecip) );
+
+        //-| Note that you could do pp/t and not be terribly inefficient since
+        //-| SpaceVector/t itself takes 1/t and multiplies.  The code here saves
+        //-| a redundant check for t=0.
+
+  // Boost both vectors.  Since we have the same boost, there is no need
+  // to repeat the beta and gamma calculation; and there is no question
+  // about beta >= 1.  That is why we don't just call w.boosted().
+
+  double b2 = vTotal2*tRecip*tRecip;
+
+  register double gamma = sqrt(1./(1.-b2));
+  register double boostDotV1 = boost.dot(pp);
+  register double gm1_b2 = (gamma-1)/b2;
+
+  HepLorentzVector w1 ( pp   + ((gm1_b2)*boostDotV1+gamma*ee) * boost,
+                     gamma * (ee + boostDotV1) );
+
+  register double boostDotV2 = boost.dot(w.pp);
+  HepLorentzVector w2 ( w.pp + ((gm1_b2)*boostDotV2+gamma*w.ee) * boost,
+                     gamma * (w.ee + boostDotV2) );
+
+  return (w1.isNear(w2, epsilon));
+
+} /* isNearCM() */
+
+double HepLorentzVector::howNearCM(const HepLorentzVector & w) const {
+
+  double tTotal = (ee + w.ee);
+  Hep3Vector vTotal (pp + w.pp);
+  double vTotal2 = vTotal.mag2();
+
+  if ( vTotal2 >= tTotal*tTotal ) {
+    // Either one or both vectors are spacelike, or the dominant T components
+    // are in opposite directions.  So boosting and testing makes no sense;
+    // but we do consider two exactly equal vectors to be equal in any frame,
+    // even if they are spacelike and can't be boosted to a CM frame.
+    if (*this == w) {
+      return 0;
+    } else {
+      return 1;
+    }
+  }
+
+  if ( vTotal2 == 0 ) {  // no boost needed!
+    return (howNear(w));
+  }
+
+  // Find the boost to the CM frame.  We know that the total vector is timelike.
+
+  double tRecip = 1./tTotal;
+  Hep3Vector boost ( vTotal * (-tRecip) );
+
+        //-| Note that you could do pp/t and not be terribly inefficient since
+        //-| SpaceVector/t itself takes 1/t and multiplies.  The code here saves
+        //-| a redundant check for t=0.
+
+  // Boost both vectors.  Since we have the same boost, there is no need
+  // to repeat the beta and gamma calculation; and there is no question
+  // about beta >= 1.  That is why we don't just call w.boosted().
+
+  double b2 = vTotal2*tRecip*tRecip;
+  if ( b2 >= 1 ) {			// NaN-proofing
+    ZMthrowC ( ZMxpvTachyonic (
+	"boost vector in howNearCM appears to be tachyonic"));
+  }
+  register double gamma = sqrt(1./(1.-b2));
+  register double boostDotV1 = boost.dot(pp);
+  register double gm1_b2 = (gamma-1)/b2;
+
+  HepLorentzVector w1 ( pp   + ((gm1_b2)*boostDotV1+gamma*ee) * boost,
+                     gamma * (ee + boostDotV1) );
+
+  register double boostDotV2 = boost.dot(w.pp);
+  HepLorentzVector w2 ( w.pp + ((gm1_b2)*boostDotV2+gamma*w.ee) * boost,
+                     gamma * (w.ee + boostDotV2) );
+
+  return (w1.howNear(w2));
+
+} /* howNearCM() */
+
+//-************
+// deltaR
+// isParallel
+// howParallel
+// howLightlike
+//-************
+
+double HepLorentzVector::deltaR ( const HepLorentzVector & w ) const {
+
+  double a = eta() - w.eta();
+  double b = pp.deltaPhi(w.getV());
+
+  return sqrt ( a*a + b*b );
+
+} /* deltaR */
+
+// If the difference (in the Euclidean norm) of the normalized (in Euclidean
+// norm) 4-vectors is small, then those 4-vectors are considered nearly
+// parallel.
+
+bool HepLorentzVector::isParallel (const HepLorentzVector & w, double epsilon) const {
+  double norm = euclideanNorm();
+  double wnorm = w.euclideanNorm();
+  if ( norm == 0 ) {
+    if ( wnorm == 0 ) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+  if ( wnorm == 0 ) {
+    return false;
+  }
+  HepLorentzVector w1 = *this / norm;
+  HepLorentzVector w2 = w / wnorm;
+  return ( (w1-w2).euclideanNorm2() <= epsilon*epsilon );
+} /* isParallel */
+
+
+double HepLorentzVector::howParallel (const HepLorentzVector & w) const {
+
+  double norm = euclideanNorm();
+  double wnorm = w.euclideanNorm();
+  if ( norm == 0 ) {
+    if ( wnorm == 0 ) {
+      return 0;
+    } else {
+      return 1;
+    }
+  }
+  if ( wnorm == 0 ) {
+    return 1;
+  }
+
+  HepLorentzVector w1 = *this / norm;
+  HepLorentzVector w2 = w / wnorm;
+  double x = (w1-w2).euclideanNorm();
+  return (x < 1) ? x : 1;
+
+} /* howParallel */
+
+double HepLorentzVector::howLightlike() const {
+  double m2 = fabs(restMass2());
+  double twoT2 = 2*ee*ee;
+  if (m2 < twoT2) {
+    return m2/twoT2;
+  } else {
+    return 1;
+  }
+} /* HowLightlike */
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzVectorK.cc
===================================================================
--- trunk/CLHEP/src/LorentzVectorK.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVectorK.cc	(revision 4)
@@ -0,0 +1,237 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is part of the implementation of the HepLorentzVector class:
+// Those methods which originated from ZOOM and which deal with relativistic
+// kinematic properties.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+//-******************
+// Metric flexibility
+//-******************
+
+ZMpvMetric_t HepLorentzVector::setMetric( ZMpvMetric_t m ) {
+  ZMpvMetric_t oldMetric = (metric > 0) ? TimePositive : TimeNegative;
+  if ( m == TimeNegative ) {
+    metric = -1.0;
+  } else {
+    metric =  1.0;
+  }
+  return oldMetric;
+}
+
+ZMpvMetric_t HepLorentzVector::getMetric() {
+  return ( (metric > 0) ? TimePositive : TimeNegative );
+}
+
+//-********
+// plus
+// minus
+//-********
+
+double HepLorentzVector::plus (const Hep3Vector & ref) const {
+  double r = ref.mag();
+  if (r == 0) {
+    ZMthrowA (ZMxpvZeroVector(
+      "A zero vector used as reference to LorentzVector plus-part"));
+    return ee;
+  }
+  return ee + pp.dot(ref)/r;
+} /* plus */
+
+double HepLorentzVector::minus (const Hep3Vector & ref) const {
+  double r = ref.mag();
+  if (r == 0) {
+    ZMthrowA (ZMxpvZeroVector(
+      "A zero vector used as reference to LorentzVector minus-part"));
+    return ee;
+  }
+  return ee - pp.dot(ref)/r;
+} /* plus */
+
+HepLorentzVector HepLorentzVector::rest4Vector() const {
+  return HepLorentzVector (0, 0, 0, (t() < 0.0 ? -m() : m()));
+}
+
+//-********
+// beta
+// gamma
+//-********
+
+double HepLorentzVector::beta() const {
+  if (ee == 0) {
+    if (pp.mag2() == 0) {
+      return 0;
+    } else {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "beta computed for HepLorentzVector with t=0 -- infinite result"));
+    return 1./ee;
+    }
+  }
+  if (restMass2() <= 0) {
+    ZMthrowC (ZMxpvTachyonic(
+      "beta computed for a non-timelike HepLorentzVector"));
+        // result will make analytic sense but is physically meaningless
+  }
+  return sqrt (pp.mag2() / (ee*ee)) ;
+} /* beta */
+
+double HepLorentzVector::gamma() const {
+  double v2 = pp.mag2();
+  double t2 = ee*ee;
+  if (ee == 0) {
+    if (pp.mag2() == 0) {
+      return 1;
+    } else {
+    ZMthrowC (ZMxpvInfiniteVector(
+      "gamma computed for HepLorentzVector with t=0 -- zero result"));
+    return 0;
+    }
+  }
+  if (t2 < v2) {
+    ZMthrowA (ZMxpvSpacelike(
+      "gamma computed for a spacelike HepLorentzVector -- imaginary result"));
+        // analytic result would be imaginary.
+    return 0;
+  } else if ( t2 == v2 ) {
+    ZMthrowA (ZMxpvInfinity(
+      "gamma computed for a lightlike HepLorentzVector -- infinite result"));
+  }
+  return 1./sqrt(1. - v2/t2 );
+} /* gamma */
+
+
+//-***************
+// rapidity
+// pseudorapidity
+// eta
+//-***************
+
+double HepLorentzVector::rapidity() const {
+  register double z = pp.getZ();
+  if (fabs(ee) == fabs(z)) {
+    ZMthrowA (ZMxpvInfinity(
+      "rapidity for 4-vector with |E| = |Pz| -- infinite result"));
+  }
+  if (fabs(ee) < fabs(z)) {
+    ZMthrowA (ZMxpvSpacelike(
+      "rapidity for spacelike 4-vector with |E| < |Pz| -- undefined"));
+    return 0;
+  }
+  double q = (ee + z) / (ee - z);
+        //-| This cannot be negative now, since both numerator
+        //-| and denominator have the same sign as ee.
+  return .5 * log(q);
+} /* rapidity */
+
+double HepLorentzVector::rapidity(const Hep3Vector & ref) const {
+  register double r = ref.mag2();
+  if (r == 0) {
+    ZMthrowA (ZMxpvZeroVector(
+      "A zero vector used as reference to LorentzVector rapidity"));
+    return 0;
+  }
+  register double vdotu = pp.dot(ref)/sqrt(r);
+  if (fabs(ee) == fabs(vdotu)) {
+    ZMthrowA (ZMxpvInfinity(
+      "rapidity for 4-vector with |E| = |Pu| -- infinite result"));
+  }
+  if (fabs(ee) < fabs(vdotu)) {
+    ZMthrowA (ZMxpvSpacelike(
+      "rapidity for spacelike 4-vector with |E| < |P*ref| -- undefined "));
+    return 0;
+  }
+  double q = (ee + vdotu) / (ee - vdotu);
+  return .5 * log(q);
+} /* rapidity(ref) */
+
+double HepLorentzVector::coLinearRapidity() const {
+  register double v = pp.mag();
+  if (fabs(ee) == fabs(v)) {
+    ZMthrowA (ZMxpvInfinity(
+      "co-Linear rapidity for 4-vector with |E| = |P| -- infinite result"));
+  }
+  if (fabs(ee) < fabs(v)) {
+    ZMthrowA (ZMxpvSpacelike(
+      "co-linear rapidity for spacelike 4-vector -- undefined"));
+    return 0;
+  }
+  double q = (ee + v) / (ee - v);
+  return .5 * log(q);
+} /* rapidity */
+
+//-*************
+// invariantMass
+//-*************
+
+double HepLorentzVector::invariantMass(const HepLorentzVector & w) const {
+  double m2 = invariantMass2(w);
+  if (m2 < 0) {
+    // We should find out why:
+    if ( ee * w.ee < 0 ) {
+      ZMthrowA (ZMxpvNegativeMass(
+        "invariant mass meaningless: \n"
+        "a negative-mass input led to spacelike 4-vector sum" ));
+      return 0;
+    } else if ( (isSpacelike() && !isLightlike()) ||
+                (w.isSpacelike() && !w.isLightlike()) ) {
+      ZMthrowA (ZMxpvSpacelike(
+        "invariant mass meaningless because of spacelike input"));
+      return 0;
+    } else {
+      // Invariant mass squared for a pair of timelike or lightlike vectors
+      // mathematically cannot be negative.  If the vectors are within the
+      // tolerance of being lightlike or timelike, we can assume that prior
+      // or current roundoffs have caused the negative result, and return 0
+      // without comment.
+      return 0;
+    }
+  }
+  return (ee+w.ee >=0 ) ? sqrt(m2) : - sqrt(m2);
+} /* invariantMass */
+
+//-***************
+// findBoostToCM
+//-***************
+
+Hep3Vector HepLorentzVector::findBoostToCM() const {
+  return -boostVector();
+} /* boostToCM() */
+
+Hep3Vector HepLorentzVector::findBoostToCM (const HepLorentzVector & w) const {
+  double t = ee + w.ee;
+  Hep3Vector v = pp + w.pp;
+  if (t == 0) {
+    if (v.mag2() == 0) {
+      return Hep3Vector(0,0,0);
+    } else {
+    ZMthrowA (ZMxpvInfiniteVector(
+    "boostToCM computed for two 4-vectors with combined t=0 -- "
+        "infinite result"));
+    return Hep3Vector(v*(1./t)); // Yup, 1/0 -- that is how we return infinity
+    }
+  }
+  if (t*t - v.mag2() <= 0) {
+    ZMthrowC (ZMxpvTachyonic(
+    "boostToCM  computed for pair of HepLorentzVectors with non-timelike sum"));
+        // result will make analytic sense but is physically meaningless
+  }
+  return Hep3Vector(v * (-1./t));
+} /* boostToCM(w) */
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/LorentzVectorL.cc
===================================================================
--- trunk/CLHEP/src/LorentzVectorL.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVectorL.cc	(revision 4)
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is part of the implementation of the HepLorentzVector class:
+// Those methods which might, if coded in other modules, force loading 
+// of the LorentzRotation.cc code module.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+
+namespace CLHEP  {
+
+HepLorentzVector &
+HepLorentzVector::operator *= (const HepLorentzRotation & m) {
+  return *this = m.vectorMultiplication(*this);
+}
+
+HepLorentzVector &
+HepLorentzVector::transform(const HepLorentzRotation & m){
+  return *this = m.vectorMultiplication(*this);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/LorentzVectorR.cc
===================================================================
--- trunk/CLHEP/src/LorentzVectorR.cc	(revision 4)
+++ trunk/CLHEP/src/LorentzVectorR.cc	(revision 4)
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is part of the implementation of the HepLorentzVector class:
+// Those methods which might, if coded in LorentzVector.cc, force loading 
+// of the Rotation.cc code module.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/LorentzVector.h"
+
+namespace CLHEP  {
+
+HepLorentzVector &  HepLorentzVector::rotate(double a, const Hep3Vector &v) {
+  pp.rotate(a,v);
+  return *this;
+}
+
+HepLorentzVector & HepLorentzVector::rotate ( const Hep3Vector & axis, 
+					      double delta )		{
+  pp.rotate (axis, delta);
+  return *this;
+}
+
+HepLorentzVector & HepLorentzVector::rotate ( const HepAxisAngle & ax ) {
+  pp.rotate (ax);
+  return *this;
+}
+
+HepLorentzVector & HepLorentzVector::rotate ( const HepEulerAngles & e ) {
+  pp.rotate (e);
+  return *this;
+}
+
+HepLorentzVector & HepLorentzVector::rotate ( double phi,
+		                              double theta,
+                		              double psi ) {
+  pp.rotate (phi, theta, psi);
+  return *this;
+}
+
+HepLorentzVector rotationOf (const HepLorentzVector & vec, 
+			     const Hep3Vector & axis,  
+			     double delta) {
+  HepLorentzVector vv (vec);
+  return vv.rotate (axis, delta);
+}
+
+HepLorentzVector rotationOf 
+	(const HepLorentzVector & vec, const HepAxisAngle &ax ) {
+  HepLorentzVector vv (vec);
+  return vv.rotate (ax);
+}
+
+HepLorentzVector rotationOf
+	(const HepLorentzVector & vec, const HepEulerAngles &e ) {
+  HepLorentzVector vv (vec);
+  return vv.rotate (e);
+}
+
+HepLorentzVector rotationOf (const HepLorentzVector & vec, 
+				   double phi,
+				   double theta,
+				   double psi) {
+  HepLorentzVector vv (vec);
+  return vv.rotate (phi, theta, psi);
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/Rotation.cc
===================================================================
--- trunk/CLHEP/src/Rotation.cc	(revision 4)
+++ trunk/CLHEP/src/Rotation.cc	(revision 4)
@@ -0,0 +1,198 @@
+// -*- C++ -*-
+// $Id: Rotation.cc,v 1.1 2008-06-04 14:15:07 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the parts of the the HepRotation class which
+// were present in the original CLHEP before the merge with ZOOM PhysicsVectors.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <iostream>
+#include <cmath>
+
+using std::abs;
+
+namespace CLHEP  {
+
+static inline double safe_acos (double x) {
+  if (abs(x) <= 1.0) return acos(x);
+  return ( (x>0) ? 0 : CLHEP::pi );
+}
+
+double HepRotation::operator() (int i, int j) const {
+  if (i == 0) {
+    if (j == 0) { return xx(); }
+    if (j == 1) { return xy(); }
+    if (j == 2) { return xz(); } 
+  } else if (i == 1) {
+    if (j == 0) { return yx(); }
+    if (j == 1) { return yy(); }
+    if (j == 2) { return yz(); } 
+  } else if (i == 2) {
+    if (j == 0) { return zx(); }
+    if (j == 1) { return zy(); }
+    if (j == 2) { return zz(); } 
+  } 
+  std::cerr << "HepRotation subscripting: bad indices "
+       << "(" << i << "," << j << ")" << std::endl;
+  return 0.0;
+} 
+
+HepRotation & HepRotation::rotate(double a, const Hep3Vector& axis) {
+  if (a != 0.0) {
+    double ll = axis.mag();
+    if (ll == 0.0) {
+      ZMthrowC (ZMxpvZeroVector("HepRotation: zero axis"));
+    }else{
+      double sa = sin(a), ca = cos(a);
+      double dx = axis.x()/ll, dy = axis.y()/ll, dz = axis.z()/ll;   
+      HepRotation m(
+	ca+(1-ca)*dx*dx,          (1-ca)*dx*dy-sa*dz,    (1-ca)*dx*dz+sa*dy,
+	   (1-ca)*dy*dx+sa*dz, ca+(1-ca)*dy*dy,          (1-ca)*dy*dz-sa*dx,
+	   (1-ca)*dz*dx-sa*dy,    (1-ca)*dz*dy+sa*dx, ca+(1-ca)*dz*dz );
+      transform(m);
+    }
+  }
+  return *this;
+}
+
+HepRotation & HepRotation::rotateX(double a) {
+  double c = cos(a);
+  double s = sin(a);
+  double x = ryx, y = ryy, z = ryz; 
+  ryx = c*x - s*rzx;
+  ryy = c*y - s*rzy;
+  ryz = c*z - s*rzz;
+  rzx = s*x + c*rzx;
+  rzy = s*y + c*rzy;
+  rzz = s*z + c*rzz;
+  return *this;
+}
+
+HepRotation & HepRotation::rotateY(double a){
+  double c = cos(a);
+  double s = sin(a);
+  double x = rzx, y = rzy, z = rzz; 
+  rzx = c*x - s*rxx;
+  rzy = c*y - s*rxy;
+  rzz = c*z - s*rxz;
+  rxx = s*x + c*rxx;
+  rxy = s*y + c*rxy;
+  rxz = s*z + c*rxz;
+  return *this;
+}
+
+HepRotation & HepRotation::rotateZ(double a) {
+  double c = cos(a);
+  double s = sin(a);
+  double x = rxx, y = rxy, z = rxz; 
+  rxx = c*x - s*ryx;
+  rxy = c*y - s*ryy;
+  rxz = c*z - s*ryz;
+  ryx = s*x + c*ryx;
+  ryy = s*y + c*ryy;
+  ryz = s*z + c*ryz;
+  return *this;
+}
+
+HepRotation & HepRotation::rotateAxes(const Hep3Vector &newX,
+				      const Hep3Vector &newY,
+				      const Hep3Vector &newZ) {
+  double del = 0.001;
+  Hep3Vector w = newX.cross(newY);
+
+  if (abs(newZ.x()-w.x()) > del ||
+      abs(newZ.y()-w.y()) > del ||
+      abs(newZ.z()-w.z()) > del ||
+      abs(newX.mag2()-1.) > del ||
+      abs(newY.mag2()-1.) > del || 
+      abs(newZ.mag2()-1.) > del ||
+      abs(newX.dot(newY)) > del ||
+      abs(newY.dot(newZ)) > del ||
+      abs(newZ.dot(newX)) > del) {
+    std::cerr << "HepRotation::rotateAxes: bad axis vectors" << std::endl;
+    return *this;
+  }else{
+    return transform(HepRotation(newX.x(), newY.x(), newZ.x(),
+                                 newX.y(), newY.y(), newZ.y(),
+                                 newX.z(), newY.z(), newZ.z()));
+  }
+}
+
+double HepRotation::phiX() const {
+  return (yx() == 0.0 && xx() == 0.0) ? 0.0 : std::atan2(yx(),xx());
+}
+
+double HepRotation::phiY() const {
+  return (yy() == 0.0 && xy() == 0.0) ? 0.0 : std::atan2(yy(),xy());
+}
+
+double HepRotation::phiZ() const {
+  return (yz() == 0.0 && xz() == 0.0) ? 0.0 : std::atan2(yz(),xz());
+}
+
+double HepRotation::thetaX() const {
+  return safe_acos(zx());
+}
+
+double HepRotation::thetaY() const {
+  return safe_acos(zy());
+}
+
+double HepRotation::thetaZ() const {
+  return safe_acos(zz());
+}
+
+void HepRotation::getAngleAxis(double &angle, Hep3Vector &axis) const {
+  double cosa  = 0.5*(xx()+yy()+zz()-1);
+  double cosa1 = 1-cosa;
+  if (cosa1 <= 0) {
+    angle = 0;
+    axis  = Hep3Vector(0,0,1);
+  }else{
+    double x=0, y=0, z=0;
+    if (xx() > cosa) x = sqrt((xx()-cosa)/cosa1);
+    if (yy() > cosa) y = sqrt((yy()-cosa)/cosa1);
+    if (zz() > cosa) z = sqrt((zz()-cosa)/cosa1);
+    if (zy() < yz()) x = -x;
+    if (xz() < zx()) y = -y;
+    if (yx() < xy()) z = -z;
+    angle = (cosa < -1.) ? acos(-1.) : acos(cosa);
+    axis  = Hep3Vector(x,y,z);
+  }
+}
+
+bool HepRotation::isIdentity() const {
+  return  (rxx == 1.0 && rxy == 0.0 && rxz == 0.0 &&
+           ryx == 0.0 && ryy == 1.0 && ryz == 0.0 &&
+           rzx == 0.0 && rzy == 0.0 && rzz == 1.0) ? true : false;
+}
+
+int HepRotation::compare ( const HepRotation & r ) const {
+       if (rzz<r.rzz) return -1; else if (rzz>r.rzz) return 1;
+  else if (rzy<r.rzy) return -1; else if (rzy>r.rzy) return 1;
+  else if (rzx<r.rzx) return -1; else if (rzx>r.rzx) return 1;
+  else if (ryz<r.ryz) return -1; else if (ryz>r.ryz) return 1;
+  else if (ryy<r.ryy) return -1; else if (ryy>r.ryy) return 1;
+  else if (ryx<r.ryx) return -1; else if (ryx>r.ryx) return 1;
+  else if (rxz<r.rxz) return -1; else if (rxz>r.rxz) return 1;
+  else if (rxy<r.rxy) return -1; else if (rxy>r.rxy) return 1;
+  else if (rxx<r.rxx) return -1; else if (rxx>r.rxx) return 1;
+  else return 0;
+}
+
+
+const HepRotation HepRotation::IDENTITY;
+
+}  // namespace CLHEP
+
+
Index: trunk/CLHEP/src/RotationA.cc
===================================================================
--- trunk/CLHEP/src/RotationA.cc	(revision 4)
+++ trunk/CLHEP/src/RotationA.cc	(revision 4)
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of those methods of the HepRotation class which
+// were introduced when ZOOM PhysicsVectors was merged in, and which involve 
+// the angle/axis representation of a Rotation.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <iostream>
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  Constructors and Assignment:
+
+// axis and angle
+
+HepRotation & HepRotation::set( const Hep3Vector & axis, double delta ) {
+
+  register double sinDelta = sin(delta), cosDelta = cos(delta);
+  register double oneMinusCosDelta = 1.0 - cosDelta;
+
+  Hep3Vector u = axis.unit();
+
+  register double uX = u.getX();
+  register double uY = u.getY();
+  register double uZ = u.getZ();
+
+  rxx = oneMinusCosDelta * uX * uX  +  cosDelta;
+  rxy = oneMinusCosDelta * uX * uY  -  sinDelta * uZ;
+  rxz = oneMinusCosDelta * uX * uZ  +  sinDelta * uY;
+
+  ryx = oneMinusCosDelta * uY * uX  +  sinDelta * uZ;
+  ryy = oneMinusCosDelta * uY * uY  +  cosDelta;
+  ryz = oneMinusCosDelta * uY * uZ  -  sinDelta * uX;
+
+  rzx = oneMinusCosDelta * uZ * uX  -  sinDelta * uY;
+  rzy = oneMinusCosDelta * uZ * uY  +  sinDelta * uX;
+  rzz = oneMinusCosDelta * uZ * uZ  +  cosDelta;
+
+  return  *this;
+
+} // HepRotation::set(axis, delta)
+
+HepRotation::HepRotation ( const Hep3Vector & axis, double delta ) 
+{
+  set( axis, delta );
+}  
+HepRotation & HepRotation::set( const HepAxisAngle & ax ) {
+  return  set ( ax.axis(), ax.delta() );
+}
+HepRotation::HepRotation ( const HepAxisAngle & ax ) 
+{
+  set ( ax.axis(), ax.delta() );
+}
+
+
+
+
+double    HepRotation::delta() const {
+
+  double cosdelta = (rxx + ryy + rzz - 1.0) / 2.0;
+  if (cosdelta > 1.0) {
+    return 0;
+  } else if (cosdelta < -1.0) {
+    return CLHEP::pi;
+  } else {
+    return  acos( cosdelta ); // Already safe due to the cosdelta > 1 check
+  }
+
+} // delta()
+
+Hep3Vector HepRotation::axis () const {
+
+  // Determine 2*sin(delta) times the u components (I call this uX, uY, Uz)
+  // Normalization is not needed; it will be done when returning the 3-Vector
+
+  double  Uz = ryx - rxy;
+  double  Uy = rxz - rzx;
+  double  Ux = rzy - ryz;
+
+  if ( (Uz==0) && (Uy==0) && (Ux==0) ) {
+    if        ( rzz>0 ) {
+      return Hep3Vector(0,0,1);
+    } else if ( ryy>0 ) {
+      return Hep3Vector(0,1,0);
+    } else {
+      return Hep3Vector(1,0,0);
+    }
+  } else {
+    return  Hep3Vector( Ux, Uy, Uz ).unit();
+  }
+
+} // axis()
+
+HepAxisAngle HepRotation::axisAngle() const {
+
+  return HepAxisAngle (axis(), delta());
+
+} // axisAngle() 
+
+
+void HepRotation::setAxis (const Hep3Vector & axis) {
+  set ( axis, delta() );
+}
+
+void HepRotation::setDelta (double delta) {
+  set ( axis(), delta );
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationC.cc
===================================================================
--- trunk/CLHEP/src/RotationC.cc	(revision 4)
+++ trunk/CLHEP/src/RotationC.cc	(revision 4)
@@ -0,0 +1,210 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotation class which
+// were introduced when ZOOM PhysicsVectors was merged in, which involve
+// correcting user-supplied data which is supposed to form a Rotation, or
+// rectifying a rotation matrix which may have drifted due to roundoff.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// --------- Helper methods (private) for setting from 3 columns:
+
+bool HepRotation::setCols 
+    ( const Hep3Vector & u1, const Hep3Vector & u2, const Hep3Vector & u3,
+      double u1u2,
+      Hep3Vector & v1, Hep3Vector & v2, Hep3Vector & v3 ) const {
+
+  if ( (1-fabs(u1u2)) <= Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvParallelCols(
+      "All three cols supplied for a Rotation are parallel --"
+        "\n    an arbitrary rotation will be returned"));
+    setArbitrarily (u1, v1, v2, v3);
+    return true;
+  }
+
+  v1 = u1;
+  v2  = Hep3Vector(u2 - u1u2 * u1).unit();
+  v3 = v1.cross(v2);
+  if ( v3.dot(u3) >= 0 ) {
+    return true;
+  } else {
+    return false;	// looks more like a reflection in this case!
+  }
+
+} // HepRotation::setCols 
+
+void HepRotation::setArbitrarily (const Hep3Vector & colX, 
+   Hep3Vector & v1, Hep3Vector & v2, Hep3Vector & v3) const {
+
+  // We have all three col's parallel.  Warnings already been given;
+  // this just supplies a result which is a valid rotation.
+
+  v1 = colX.unit();
+  v2 = v1.cross(Hep3Vector(0,0,1));
+  if (v2.mag2() != 0) {
+    v2 = v2.unit();
+  } else {
+    v2 = Hep3Vector(1,0,0);
+  }
+  v3 = v1.cross(v2);
+
+  return;
+
+} // HepRotation::setArbitrarily 
+
+
+
+
+// ----------  Constructors and Assignment:
+
+// 3 orthogonal columns or rows
+
+HepRotation & HepRotation::set( const Hep3Vector & colX,
+                            	const Hep3Vector & colY,
+                          	const Hep3Vector & colZ ) {
+  Hep3Vector ucolX = colX.unit();
+  Hep3Vector ucolY = colY.unit();
+  Hep3Vector ucolZ = colZ.unit();
+
+  double u1u2 = ucolX.dot(ucolY);
+  double f12  = fabs(u1u2);
+  if ( f12 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+      "col's X and Y supplied for Rotation are not close to orthogonal"));
+  }
+  double u1u3 = ucolX.dot(ucolZ);
+  double f13  = fabs(u1u3);
+  if ( f13 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+      "col's X and Z supplied for Rotation are not close to orthogonal"));
+  }
+  double u2u3 = ucolY.dot(ucolZ);
+  double f23  = fabs(u2u3);
+  if ( f23 > Hep4RotationInterface::tolerance ) {
+    ZMthrowC (ZMxpvNotOrthogonal(
+      "col's Y and Z supplied for Rotation are not close to orthogonal"));
+  }
+
+  Hep3Vector v1, v2, v3;
+  bool isRotation;
+  if ( (f12 <= f13) && (f12 <= f23) ) {
+    isRotation = setCols ( ucolX, ucolY, ucolZ, u1u2, v1, v2, v3 );
+    if ( !isRotation ) {
+      ZMthrowC (ZMxpvImproperRotation(
+      "col's X Y and Z supplied form closer to a reflection than a Rotation "
+        "\n     col Z is set to col X cross col Y"));
+    }
+  } else if ( f13 <= f23 ) {
+    isRotation = setCols ( ucolZ, ucolX, ucolY, u1u3, v3, v1, v2 );
+    if ( !isRotation ) {
+      ZMthrowC (ZMxpvImproperRotation(
+      "col's X Y and Z supplied form closer to a reflection than a Rotation "
+        "\n     col Y is set to col Z cross col X"));
+    }
+  } else {
+    isRotation = setCols ( ucolY, ucolZ, ucolX, u2u3, v2, v3, v1 );
+    if ( !isRotation ) {
+      ZMthrowC (ZMxpvImproperRotation(
+      "col's X Y and Z supplied form closer to a reflection than a Rotation "
+        "\n     col X is set to col Y cross col Z"));
+    }
+  }
+
+  rxx = v1.x();  ryx = v1.y(); rzx = v1.z();
+  rxy = v2.x();  ryy = v2.y(); rzy = v2.z();
+  rxz = v3.x();  ryz = v3.y(); rzz = v3.z();
+
+  return *this;
+
+}  // HepRotation::set(colX, colY, colZ)
+
+HepRotation::HepRotation ( const Hep3Vector & colX,
+              		   const Hep3Vector & colY,
+		           const Hep3Vector & colZ ) 
+{
+  set (colX, colY, colZ);
+}
+
+HepRotation & HepRotation::setRows( const Hep3Vector & rowX,
+                           	    const Hep3Vector & rowY,
+                              	    const Hep3Vector & rowZ ) {
+  set (rowX, rowY, rowZ);
+  invert();
+  return *this;
+}
+
+
+
+// ------- Rectify a near-rotation
+
+void HepRotation::rectify() {
+  // Assuming the representation of this is close to a true Rotation,
+  // but may have drifted due to round-off error from many operations,
+  // this forms an "exact" orthonormal matrix for the rotation again.
+
+  // The first step is to average with the transposed inverse.  This
+  // will correct for small errors such as those occuring when decomposing
+  // a LorentzTransformation.  Then we take the bull by the horns and
+  // formally extract the axis and delta (assuming the Rotation were true)
+  // and re-setting the rotation according to those.
+
+  double det =  rxx * ryy * rzz +
+                   rxy * ryz * rzx +
+                   rxz * ryx * rzy -
+                   rxx * ryz * rzy -
+                   rxy * ryx * rzz -
+                   rxz * ryy * rzx   ;
+  if (det <= 0) {
+    ZMthrowA(ZMxpvImproperRotation(
+        "Attempt to rectify a Rotation with determinant <= 0\n"));
+    return;
+  }
+  double di = 1.0 / det;
+
+  // xx, xy, ... are components of inverse matrix:
+  double xx = (ryy * rzz - ryz * rzy) * di;
+  double xy = (rzy * rxz - rzz * rxy) * di;
+  double xz = (rxy * ryz - rxz * ryy) * di;
+  double yx = (ryz * rzx - ryx * rzz) * di;
+  double yy = (rzz * rxx - rzx * rxz) * di;
+  double yz = (rxz * ryx - rxx * ryz) * di;
+  double zx = (ryx * rzy - ryy * rzx) * di;
+  double zy = (rzx * rxy - rzy * rxx) * di;
+  double zz = (rxx * ryy - rxy * ryx) * di;
+
+  // Now average with the TRANSPOSE of that:
+  rxx = .5*(rxx + xx);
+  rxy = .5*(rxy + yx);
+  rxz = .5*(rxz + zx);
+  ryx = .5*(ryx + xy);
+  ryy = .5*(ryy + yy);
+  ryz = .5*(ryz + zy);
+  rzx = .5*(rzx + xz);
+  rzy = .5*(rzy + yz);
+  rzz = .5*(rzz + zz);
+
+  // Now force feed this improved rotation
+  double del = delta();
+  Hep3Vector u = axis();
+  u = u.unit(); // Because if the rotation is inexact, then the
+                // axis() returned will not have length 1!
+  set(u, del);
+
+} // rectify()
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/RotationE.cc
===================================================================
--- trunk/CLHEP/src/RotationE.cc	(revision 4)
+++ trunk/CLHEP/src/RotationE.cc	(revision 4)
@@ -0,0 +1,287 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotation class which
+// were introduced when ZOOM PhysicsVectors was merged in, and which involve
+// Euler Angles representation.
+//
+// Apr 28, 2003  mf  Modified way of computing Euler angles to avoid flawed
+//                   answers in the case where theta is near 0 of pi, and
+//                   the matrix is not a perfect rotation (due to roundoff).
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/EulerAngles.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+#include <stdlib.h>
+
+using std::abs;
+
+namespace CLHEP  {
+
+static inline double safe_acos (double x) {
+  if (abs(x) <= 1.0) return acos(x);
+  return ( (x>0) ? 0 : CLHEP::pi );
+}
+
+// ----------  Constructors and Assignment:
+
+// Euler angles
+
+HepRotation & HepRotation::set(double phi, double theta, double psi) {
+
+  register double sinPhi   = sin( phi   ), cosPhi   = cos( phi   );
+  register double sinTheta = sin( theta ), cosTheta = cos( theta );
+  register double sinPsi   = sin( psi   ), cosPsi   = cos( psi   );
+
+  rxx =   cosPsi * cosPhi - cosTheta * sinPhi * sinPsi;
+  rxy =   cosPsi * sinPhi + cosTheta * cosPhi * sinPsi;
+  rxz =   sinPsi * sinTheta;
+
+  ryx = - sinPsi * cosPhi - cosTheta * sinPhi * cosPsi;
+  ryy = - sinPsi * sinPhi + cosTheta * cosPhi * cosPsi;
+  ryz =   cosPsi * sinTheta;
+
+  rzx =   sinTheta * sinPhi;
+  rzy = - sinTheta * cosPhi;
+  rzz =   cosTheta;
+
+  return  *this;
+
+}  // Rotation::set(phi, theta, psi)
+
+HepRotation::HepRotation( double phi, double theta, double psi ) 
+{
+  set (phi, theta, psi);
+}
+HepRotation & HepRotation::set( const HepEulerAngles & e ) {
+  return set(e.phi(), e.theta(), e.psi());
+}
+HepRotation::HepRotation ( const HepEulerAngles & e ) 
+{
+  set(e.phi(), e.theta(), e.psi());
+}
+
+
+
+ 
+double HepRotation::phi  () const {
+
+  double s2 =  1.0 - rzz*rzz;
+  if (s2 < 0) {
+    ZMthrowC ( ZMxpvImproperRotation (
+        "HepRotation::phi() finds | rzz | > 1 "));
+    s2 = 0;
+  }
+  const double sinTheta = sqrt( s2 );
+
+  if (sinTheta < .01) { // For theta close to 0 or PI, use the more stable
+  			// algorithm to get all three Euler angles
+    HepEulerAngles ea = eulerAngles();
+    return ea.phi();
+  }
+  
+  const double cscTheta = 1/sinTheta;
+  double cosabsphi =  - rzy * cscTheta;
+  if ( fabs(cosabsphi) > 1 ) {	// NaN-proofing
+    ZMthrowC ( ZMxpvImproperRotation (
+      "HepRotation::phi() finds | cos phi | > 1 "));
+    cosabsphi = 1;
+  }
+  const double absPhi = acos ( cosabsphi );
+  if (rzx > 0) {
+    return   absPhi;
+  } else if (rzx < 0) {
+    return  -absPhi;
+  } else {
+    return  (rzy < 0) ? 0 : CLHEP::pi;
+  }
+
+} // phi()
+
+double HepRotation::theta() const {
+
+  return  safe_acos( rzz );
+
+} // theta()
+
+double HepRotation::psi  () const {
+
+  double sinTheta;
+  if ( fabs(rzz) > 1 ) {	// NaN-proofing
+    ZMthrowC ( ZMxpvImproperRotation (
+      "HepRotation::psi() finds | rzz | > 1"));
+    sinTheta = 0;
+  } else { 
+    sinTheta = sqrt( 1.0 - rzz*rzz );
+  }
+  
+  if (sinTheta < .01) { // For theta close to 0 or PI, use the more stable
+  			// algorithm to get all three Euler angles
+    HepEulerAngles ea = eulerAngles();
+    return ea.psi();
+  }
+
+  const double cscTheta = 1/sinTheta;
+  double cosabspsi =  ryz * cscTheta;
+  if ( fabs(cosabspsi) > 1 ) {	// NaN-proofing
+    ZMthrowC ( ZMxpvImproperRotation (
+      "HepRotation::psi() finds | cos psi | > 1"));
+    cosabspsi = 1;
+  }
+  const double absPsi = acos ( cosabspsi );
+  if (rxz > 0) {
+    return   absPsi;
+  } else if (rxz < 0) {
+    return  -absPsi;
+  } else {
+    return  (ryz > 0) ? 0 : CLHEP::pi;
+  }
+
+} // psi()
+
+
+
+// Helpers for eulerAngles():
+
+static		     
+void correctByPi ( double& psi, double& phi ) {
+  if (psi > 0) {
+    psi -= CLHEP::pi;
+  } else {
+    psi += CLHEP::pi;
+  }
+  if (phi > 0) {
+    phi -= CLHEP::pi;
+  } else {
+    phi += CLHEP::pi;
+  }  
+}
+
+static
+void correctPsiPhi ( double rxz, double rzx, double ryz, double rzy, 
+		     double& psi, double& phi ) {
+
+  // set up quatities which would be positive if sin and cosine of
+  // psi and phi were positive:
+  double w[4];
+  w[0] = rxz; w[1] = rzx; w[2] = ryz; w[3] = -rzy;
+
+  // find biggest relevant term, which is the best one to use in correcting.
+  double maxw = abs(w[0]); 
+  int imax = 0;
+  for (int i = 1; i < 4; ++i) {
+    if (abs(w[i]) > maxw) {
+      maxw = abs(w[i]);
+      imax = i;
+    }
+  }
+  // Determine if the correction needs to be applied:  The criteria are 
+  // different depending on whether a sine or cosine was the determinor: 
+  switch (imax) {
+    case 0:
+      if (w[0] > 0 && psi < 0)           correctByPi ( psi, phi );
+      if (w[0] < 0 && psi > 0)           correctByPi ( psi, phi );
+      break;
+    case 1:
+      if (w[1] > 0 && phi < 0)           correctByPi ( psi, phi );
+      if (w[1] < 0 && phi > 0)           correctByPi ( psi, phi );
+      break;
+    case 2:
+      if (w[2] > 0 && abs(psi) > CLHEP::halfpi) correctByPi ( psi, phi );    
+      if (w[2] < 0 && abs(psi) < CLHEP::halfpi) correctByPi ( psi, phi );    
+      break;
+    case 3:
+      if (w[3] > 0 && abs(phi) > CLHEP::halfpi) correctByPi ( psi, phi );    
+      if (w[3] < 0 && abs(phi) < CLHEP::halfpi) correctByPi ( psi, phi );    
+      break;
+  }          
+}
+
+
+
+HepEulerAngles HepRotation::eulerAngles() const {
+
+  // Please see the mathematical justification in eulerAngleComputations.ps
+
+  double phi, theta, psi;
+  double psiPlusPhi, psiMinusPhi;
+  
+  theta = safe_acos( rzz );
+  
+  if (rzz > 1 || rzz < -1) {
+    ZMthrowC ( ZMxpvImproperRotation (
+        "HepRotation::eulerAngles() finds | rzz | > 1 "));
+  }
+  
+  double cosTheta = rzz;
+  if (cosTheta > 1)  cosTheta = 1;
+  if (cosTheta < -1) cosTheta = -1;
+
+  if (cosTheta == 1) {
+    psiPlusPhi = atan2 ( rxy - ryx, rxx + ryy );
+    psiMinusPhi = 0;     
+
+  } else if (cosTheta >= 0) {
+
+    // In this realm, the atan2 expression for psi + phi is numerically stable
+    psiPlusPhi = atan2 ( rxy - ryx, rxx + ryy );
+
+    // psi - phi is potentially more subtle, but when unstable it is moot
+    double s = -rxy - ryx; // sin (psi-phi) * (1 - cos theta)
+    double c =  rxx - ryy; // cos (psi-phi) * (1 - cos theta)
+    psiMinusPhi = atan2 ( s, c );
+        
+  } else if (cosTheta > -1) {
+
+    // In this realm, the atan2 expression for psi - phi is numerically stable
+    psiMinusPhi = atan2 ( -rxy - ryx, rxx - ryy );
+
+   // psi + phi is potentially more subtle, but when unstable it is moot
+    double s = rxy - ryx; // sin (psi+phi) * (1 + cos theta)
+    double c = rxx + ryy; // cos (psi+phi) * (1 + cos theta)
+    psiPlusPhi = atan2 ( s, c );
+
+  } else { // cosTheta == -1
+
+    psiMinusPhi = atan2 ( -rxy - ryx, rxx - ryy );
+    psiPlusPhi = 0;
+
+  }
+  
+  psi = .5 * (psiPlusPhi + psiMinusPhi); 
+  phi = .5 * (psiPlusPhi - psiMinusPhi); 
+
+  // Now correct by pi if we have managed to get a value of psiPlusPhi
+  // or psiMinusPhi that was off by 2 pi:
+  correctPsiPhi ( rxz, rzx, ryz, rzy, psi, phi );
+  
+  return  HepEulerAngles( phi, theta, psi );
+
+} // eulerAngles()
+
+
+
+
+void HepRotation::setPhi (double phi) {
+  set ( phi, theta(), psi() );
+}
+
+void HepRotation::setTheta (double theta) {
+  set ( phi(), theta, psi() );
+}
+
+void HepRotation::setPsi (double psi) {
+  set ( phi(), theta(), psi );
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/RotationIO.cc
===================================================================
--- trunk/CLHEP/src/RotationIO.cc	(revision 4)
+++ trunk/CLHEP/src/RotationIO.cc	(revision 4)
@@ -0,0 +1,39 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the output method of the HepRotation class,
+// which was introduced when ZOOM PhysicsVectors was merged in.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+
+#include <iomanip>
+#include <iostream>
+
+namespace CLHEP  {
+
+std::ostream & HepRotation::print( std::ostream & os ) const {
+  os << "\n   [ ( " <<
+        std::setw(11) << std::setprecision(6) << xx() << "   " <<
+        std::setw(11) << std::setprecision(6) << xy() << "   " <<
+        std::setw(11) << std::setprecision(6) << xz() << ")\n"
+     << "     ( " <<
+        std::setw(11) << std::setprecision(6) << yx() << "   " <<
+        std::setw(11) << std::setprecision(6) << yy() << "   " <<
+        std::setw(11) << std::setprecision(6) << yz() << ")\n"
+     << "     ( " <<
+        std::setw(11) << std::setprecision(6) << zx() << "   " <<
+        std::setw(11) << std::setprecision(6) << zy() << "   " <<
+        std::setw(11) << std::setprecision(6) << zz() << ") ]\n";
+	return os;
+}
+
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationInterfaces.cc
===================================================================
--- trunk/CLHEP/src/RotationInterfaces.cc	(revision 4)
+++ trunk/CLHEP/src/RotationInterfaces.cc	(revision 4)
@@ -0,0 +1,41 @@
+// -*- C++ -*-
+// $Id: RotationInterfaces.cc,v 1.1 2008-06-04 14:15:09 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of those few parts of the Hep4RotationInterface
+// and Hep3RotationInterface classes which are neither inline nor pure virtual.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/RotationInterfaces.h"
+
+namespace CLHEP  {
+
+//-******************************
+//
+// Hep4RotationInterface
+//
+//-******************************
+
+double Hep4RotationInterface::getTolerance() {return tolerance;} 
+double Hep4RotationInterface::setTolerance( double tol ) {
+  double t = tolerance; tolerance = tol; return t;
+}
+
+double Hep4RotationInterface::tolerance = 
+			Hep4RotationInterface::ToleranceTicks * 1.0e-08;
+
+
+//-******************************
+//
+// Hep3RotationInterface
+//
+//-******************************
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationL.cc
===================================================================
--- trunk/CLHEP/src/RotationL.cc	(revision 4)
+++ trunk/CLHEP/src/RotationL.cc	(revision 4)
@@ -0,0 +1,63 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotation class which
+// were introduced when ZOOM PhysicsVectors was merged in, which might cause 
+// pulling in of LorentzTransformation related code units.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+// ----------  distance2 and related member functions:
+//
+// WHy do we have forms for HepLorentzRotation and HepBoost but not for 
+// HepBoostX, HepBoostY, HepBoostZ?  Because the latter can be gotten by 
+// implicit conversion to HepBoost; but if we just had HepLorentzRotation 
+// then this would involve double conversion when HepBoostX was used.
+
+double HepRotation::distance2( const HepLorentzRotation & lt  ) const {
+  HepAxisAngle a; 
+  Hep3Vector   b;
+  lt.decompose(b, a);
+  double bet = b.beta();
+  double bet2 = bet*bet;
+  HepRotation r(a);
+  return bet2/(1-bet2) + distance2(r);
+}
+
+double HepRotation::distance2( const HepBoost & lt ) const {
+  return distance2( HepLorentzRotation(lt));
+}
+
+double HepRotation::howNear( const HepLorentzRotation & lt  ) const {
+  return  sqrt( distance2( lt ) );
+}
+
+double HepRotation::howNear( const HepBoost & lt  ) const {
+  return  sqrt( distance2( lt ) );
+}
+
+bool HepRotation::isNear(   const HepLorentzRotation & lt,
+                                     double epsilon) const {
+ return  distance2( lt ) <= epsilon*epsilon;
+}
+
+bool HepRotation::isNear(   const HepBoost & lt,
+                                     double epsilon) const {
+ return  distance2( lt ) <= epsilon*epsilon;
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/RotationP.cc
===================================================================
--- trunk/CLHEP/src/RotationP.cc	(revision 4)
+++ trunk/CLHEP/src/RotationP.cc	(revision 4)
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotation class which
+// were introduced when ZOOM PhysicsVectors was merged in, other than those
+// involving Euler or axis/angle representations, lengthy corrections of
+// the rotation matrix, or I/O.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+
+#include <cmath>
+
+
+
+
+namespace CLHEP  {
+
+void HepRotation::decompose(HepAxisAngle & rotation, Hep3Vector & boost)const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotation::decompose(Hep3Vector & boost, HepAxisAngle & rotation)const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+double HepRotation::distance2( const HepRotation & r  ) const {
+  double sum = rxx * r.rxx + rxy * r.rxy + rxz * r.rxz
+                + ryx * r.ryx + ryy * r.ryy + ryz * r.ryz
+                + rzx * r.rzx + rzy * r.rzy + rzz * r.rzz;
+  double answer = 3.0 - sum;
+  return (answer >= 0 ) ? answer : 0;
+}
+
+double HepRotation::howNear(   const HepRotation & r  ) const {
+  return  sqrt( distance2( r ) );
+}
+
+bool HepRotation::isNear(   const HepRotation & r,
+                                     double epsilon) const {
+ return  distance2( r ) <= epsilon*epsilon;
+}
+
+double HepRotation::norm2() const {
+  double answer = 3.0 - rxx - ryy - rzz;
+  return (answer >= 0 ) ? answer : 0;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationX.cc
===================================================================
--- trunk/CLHEP/src/RotationX.cc	(revision 4)
+++ trunk/CLHEP/src/RotationX.cc	(revision 4)
@@ -0,0 +1,199 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotationX class which
+// were introduced when ZOOM PhysicsVectors was merged in.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/RotationX.h"
+#include "CLHEP/Vector/AxisAngle.h"
+#include "CLHEP/Vector/EulerAngles.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+#include <stdlib.h>
+#include <iostream>
+
+using std::abs;
+
+namespace CLHEP  {
+
+static inline double safe_acos (double x) {
+  if (abs(x) <= 1.0) return acos(x);
+  return ( (x>0) ? 0 : CLHEP::pi );
+}
+
+HepRotationX::HepRotationX(double delta) : 
+		d(proper(delta)), s(sin(delta)), c(cos(delta))
+{}
+
+HepRotationX & HepRotationX::set ( double delta ) {
+  d = proper(delta);
+  s = sin(d);
+  c = cos(d);
+  return *this;
+}
+
+double  HepRotationX::phi() const {
+  if ( (d > 0) && (d < CLHEP::pi) ) {
+    return CLHEP::pi;
+  } else {
+    return 0.0;
+  }
+}  // HepRotationX::phi()
+
+double  HepRotationX::theta() const {
+  return  fabs( d );
+}  // HepRotationX::theta()
+
+double  HepRotationX::psi() const {
+  if ( (d > 0) && (d < CLHEP::pi) ) {
+    return CLHEP::pi;
+  } else {
+    return 0.0;
+  }
+}  // HepRotationX::psi()
+
+HepEulerAngles HepRotationX::eulerAngles() const {
+  return HepEulerAngles(  phi(), theta(),  psi() );
+}  // HepRotationX::eulerAngles()
+
+
+// From the defining code in the implementation of CLHEP (in Rotation.cc)
+// it is clear that thetaX, phiX form the polar angles in the original
+// coordinate system of the new X axis (and similarly for phiY and phiZ).
+//
+// This code is taken directly from the original CLHEP. However, there are as
+// shown opportunities for significant speed improvement.
+
+double HepRotationX::phiX() const {
+  return (yx() == 0.0 && xx() == 0.0) ? 0.0 : atan2(yx(),xx());
+  		// or ---- return 0;
+}
+
+double HepRotationX::phiY() const {
+  return (yy() == 0.0 && xy() == 0.0) ? 0.0 : atan2(yy(),xy());
+		// or ----  return (yy() == 0.0) ? 0.0 : atan2(yy(),xy());
+}
+
+double HepRotationX::phiZ() const {
+  return (yz() == 0.0 && xz() == 0.0) ? 0.0 : atan2(yz(),xz());
+		// or ----  return (yz() == 0.0) ? 0.0 : atan2(yz(),xz());
+}
+
+double HepRotationX::thetaX() const {
+  return safe_acos(zx());
+		// or ----  return CLHEP::halfpi;
+}
+
+double HepRotationX::thetaY() const {
+  return safe_acos(zy());
+}
+
+double HepRotationX::thetaZ() const {
+  return safe_acos(zz());  
+		// or ---- return d;
+}
+
+void HepRotationX::setDelta ( double delta ) {
+  set(delta);
+}
+
+void HepRotationX::decompose
+	(HepAxisAngle & rotation, Hep3Vector & boost) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotationX::decompose
+	(Hep3Vector & boost, HepAxisAngle & rotation) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotationX::decompose
+        (HepRotation & rotation, HepBoost & boost) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+} 
+
+void HepRotationX::decompose
+        (HepBoost & boost, HepRotation & rotation) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+}
+
+double HepRotationX::distance2( const HepRotationX & r  ) const {
+  double answer = 2.0 * ( 1.0 - ( s * r.s + c * r.c ) ) ;
+  return (answer >= 0) ? answer : 0;
+}
+
+double HepRotationX::distance2( const HepRotation & r  ) const {
+  double sum =        r.xx() + 
+                		  yy() * r.yy() + yz() * r.yz()
+                		+ zy() * r.zy() + zz() * r.zz();
+  double answer = 3.0 - sum;
+  return (answer >= 0 ) ? answer : 0;
+}
+
+double HepRotationX::distance2( const HepLorentzRotation & lt  ) const {
+  HepAxisAngle a; 
+  Hep3Vector   b;
+  lt.decompose(b, a);
+  double bet = b.beta();
+  double bet2 = bet*bet;
+  HepRotation r(a);
+  return bet2/(1-bet2) + distance2(r);
+}
+
+double HepRotationX::distance2( const HepBoost & lt ) const {
+  return distance2( HepLorentzRotation(lt));
+}
+
+double HepRotationX::howNear( const HepRotationX & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationX::howNear( const HepRotation & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationX::howNear( const HepBoost & b ) const {
+  return sqrt(distance2(b));
+}
+double HepRotationX::howNear( const HepLorentzRotation & lt ) const {
+  return sqrt(distance2(lt));
+}
+bool HepRotationX::isNear(const HepRotationX & r,double epsilon)const{
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationX::isNear(const HepRotation & r,double epsilon) const{
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationX::isNear( const HepBoost & lt,double epsilon) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+
+bool HepRotationX::isNear( const HepLorentzRotation & lt,
+                                     double epsilon ) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+
+double HepRotationX::norm2() const {
+  return 2.0 - 2.0 * c;
+}
+
+std::ostream & HepRotationX::print( std::ostream & os ) const {
+  os << "\nRotation about X (" << d << 
+		") [cos d = " << c << " sin d = " << s << "]\n";
+  return os;
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/RotationXYZ.cc
===================================================================
--- trunk/CLHEP/src/RotationXYZ.cc	(revision 4)
+++ trunk/CLHEP/src/RotationXYZ.cc	(revision 4)
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of global methods involving HepRotationX, Y, or Z 
+// along with HepRotation.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#if 0
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/Rotation.h"
+#include "CLHEP/Vector/RotationX.h"
+#include "CLHEP/Vector/RotationY.h"
+#include "CLHEP/Vector/RotationZ.h"
+
+#endif // 0
+
+namespace CLHEP  {
+
+// RotationX related
+// -----------------
+
+
+// RotationY related  
+// -----------------
+
+
+// RotationZ related
+// -----------------
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationY.cc
===================================================================
--- trunk/CLHEP/src/RotationY.cc	(revision 4)
+++ trunk/CLHEP/src/RotationY.cc	(revision 4)
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotationY class which
+// were introduced when ZOOM PhysicsVectors was merged in.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/RotationY.h"
+#include "CLHEP/Vector/AxisAngle.h"
+#include "CLHEP/Vector/EulerAngles.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+#include <stdlib.h>
+#include <iostream>
+
+using std::abs;
+
+namespace CLHEP  {
+
+static inline double safe_acos (double x) {
+  if (abs(x) <= 1.0) return acos(x);
+  return ( (x>0) ? 0 : CLHEP::pi );
+}
+
+HepRotationY::HepRotationY(double delta) : 
+		d(proper(delta)), s(sin(delta)), c(cos(delta))
+{}
+
+HepRotationY & HepRotationY::set ( double delta ) {
+  d = proper(delta);
+  s = sin(d);
+  c = cos(d);
+  return *this;
+}
+
+double  HepRotationY::phi() const {
+  if ( d == 0 ) {
+    return 0;
+  } else if ( (d < 0) || (d == CLHEP::pi) )  {
+    return +CLHEP::halfpi;
+  } else {
+    return -CLHEP::halfpi;
+  }
+}  // HepRotationY::phi()
+
+double  HepRotationY::theta() const {
+  return  fabs( d );
+}  // HepRotationY::theta()
+
+double  HepRotationY::psi() const {
+  if ( d == 0 ) {
+    return 0;
+  } else if ( (d < 0) || (d == CLHEP::pi) )  {
+    return -CLHEP::halfpi;
+  } else {
+    return +CLHEP::halfpi;
+  }
+}  // HepRotationY::psi()
+
+HepEulerAngles HepRotationY::eulerAngles() const {
+  return HepEulerAngles(  phi(),  theta(),  psi() );
+}  // HepRotationY::eulerAngles()
+
+
+// From the defining code in the implementation of CLHEP (in Rotation.cc)
+// it is clear that thetaX, phiX form the polar angles in the original
+// coordinate system of the new X axis (and similarly for phiY and phiZ).
+//
+// This code is taken directly from the original CLHEP. However, there are as
+// shown opportunities for significant speed improvement.
+
+double HepRotationY::phiX() const {
+  return (yx() == 0.0 && xx() == 0.0) ? 0.0 : atan2(yx(),xx());
+  		// or ---- return 0;
+}
+
+double HepRotationY::phiY() const {
+  return (yy() == 0.0 && xy() == 0.0) ? 0.0 : atan2(yy(),xy());
+		// or ----  return CLHEP::halfpi;
+}
+
+double HepRotationY::phiZ() const {
+  return (yz() == 0.0 && xz() == 0.0) ? 0.0 : atan2(yz(),xz());
+		// or ----  return 0;
+}
+
+double HepRotationY::thetaX() const {
+  return safe_acos(zx());
+}
+
+double HepRotationY::thetaY() const {
+  return safe_acos(zy());
+		// or ----  return CLHEP::halfpi;
+}
+
+double HepRotationY::thetaZ() const {
+  return safe_acos(zz());  
+		// or ---- return d;
+}
+
+void HepRotationY::setDelta ( double delta ) {
+  set(delta);
+}
+
+void HepRotationY::decompose
+	(HepAxisAngle & rotation, Hep3Vector & boost) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotationY::decompose
+	(Hep3Vector & boost, HepAxisAngle & rotation) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotationY::decompose
+        (HepRotation & rotation, HepBoost & boost) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+}
+ 
+void HepRotationY::decompose
+        (HepBoost & boost, HepRotation & rotation) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+}
+
+double HepRotationY::distance2( const HepRotationY & r  ) const {
+  double answer = 2.0 * ( 1.0 - ( s * r.s + c * r.c ) ) ;
+  return (answer >= 0) ? answer : 0;
+}
+
+double HepRotationY::distance2( const HepRotation & r  ) const {
+  double sum =        xx() * r.xx()          +  xz() * r.xz()
+		   		       + r.yy() 
+                       + zx() * r.zx()          + zz() * r.zz();
+  double answer = 3.0 - sum;
+  return (answer >= 0 ) ? answer : 0;
+}
+
+double HepRotationY::distance2( const HepLorentzRotation & lt  ) const {
+  HepAxisAngle a; 
+  Hep3Vector   b;
+  lt.decompose(b, a);
+  double bet = b.beta();
+  double bet2 = bet*bet;
+  HepRotation r(a);
+  return bet2/(1-bet2) + distance2(r);
+}
+
+double HepRotationY::distance2( const HepBoost & lt ) const {
+  return distance2( HepLorentzRotation(lt));
+}
+
+double HepRotationY::howNear( const HepRotationY & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationY::howNear( const HepRotation & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationY::howNear( const HepBoost & lt ) const {
+  return sqrt(distance2(lt));
+}
+double HepRotationY::howNear( const HepLorentzRotation & lt ) const {
+  return sqrt(distance2(lt));
+}
+bool HepRotationY::isNear(const HepRotationY & r,double epsilon)const{
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationY::isNear(const HepRotation & r,double epsilon)const {
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationY::isNear( const HepBoost & lt,double epsilon) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+bool HepRotationY::isNear( const HepLorentzRotation & lt,
+                                     double epsilon) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+
+double HepRotationY::norm2() const {
+  return 2.0 - 2.0 * c;
+}
+
+std::ostream & HepRotationY::print( std::ostream & os ) const {
+  os << "\nRotation about Y (" << d <<
+                ") [cos d = " << c << " sin d = " << s << "]\n";
+  return os;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/RotationZ.cc
===================================================================
--- trunk/CLHEP/src/RotationZ.cc	(revision 4)
+++ trunk/CLHEP/src/RotationZ.cc	(revision 4)
@@ -0,0 +1,190 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of methods of the HepRotationZ class which
+// were introduced when ZOOM PhysicsVectors was merged in.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/RotationZ.h"
+#include "CLHEP/Vector/AxisAngle.h"
+#include "CLHEP/Vector/EulerAngles.h"
+#include "CLHEP/Vector/LorentzRotation.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+#include <stdlib.h>
+#include <iostream>
+
+using std::abs;
+
+namespace CLHEP  {
+
+static inline double safe_acos (double x) {
+  if (abs(x) <= 1.0) return acos(x);
+  return ( (x>0) ? 0 : CLHEP::pi );
+}
+
+HepRotationZ::HepRotationZ(double delta) : 
+		d(proper(delta)), s(sin(delta)), c(cos(delta))
+{}
+
+HepRotationZ & HepRotationZ::set ( double delta ) {
+  d = proper(delta);
+  s = sin(d);
+  c = cos(d);
+  return *this;
+}
+
+double  HepRotationZ::phi() const {
+  return  - d/2.0;
+}  // HepRotationZ::phi()
+
+double  HepRotationZ::theta() const {
+  return  0.0 ;
+}  // HepRotationZ::theta()
+
+double  HepRotationZ::psi() const {
+  return  - d/2.0;
+}  // HepRotationZ::psi()
+
+HepEulerAngles HepRotationZ::eulerAngles() const {
+  return HepEulerAngles(  phi(),  theta(),  psi() );
+}  // HepRotationZ::eulerAngles()
+
+
+// From the defining code in the implementation of CLHEP (in Rotation.cc)
+// it is clear that thetaX, phiX form the polar angles in the original
+// coordinate system of the new X axis (and similarly for phiY and phiZ).
+//
+// This code is take directly from CLHEP original.  However, there are as
+// shown opportunities for significant speed improvement.
+
+double HepRotationZ::phiX() const {
+  return (yx() == 0.0 && xx() == 0.0) ? 0.0 : atan2(yx(),xx());
+  		// or ---- return d;
+}
+
+double HepRotationZ::phiY() const {
+  return (yy() == 0.0 && xy() == 0.0) ? 0.0 : atan2(yy(),xy());
+}
+
+double HepRotationZ::phiZ() const {
+  return (yz() == 0.0 && xz() == 0.0) ? 0.0 : atan2(yz(),xz());
+		// or ---- return 0.0;
+}
+
+double HepRotationZ::thetaX() const {
+  return safe_acos(zx());
+		// or ----  return CLHEP::halfpi;
+}
+
+double HepRotationZ::thetaY() const {
+  return safe_acos(zy());
+		// or ----  return CLHEP::halfpi;
+}
+
+double HepRotationZ::thetaZ() const {
+  return safe_acos(zz());  
+		// or ---- return 0.0;
+}
+
+void HepRotationZ::setDelta ( double delta ) {
+  set(delta);
+}
+
+void HepRotationZ::decompose
+	(HepAxisAngle & rotation, Hep3Vector & boost) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+
+void HepRotationZ::decompose
+	(Hep3Vector & boost, HepAxisAngle & rotation) const {
+  boost.set(0,0,0);
+  rotation = axisAngle();
+}
+ 
+void HepRotationZ::decompose
+        (HepRotation & rotation, HepBoost & boost) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+}
+                                                                                
+void HepRotationZ::decompose
+        (HepBoost & boost, HepRotation & rotation) const {
+  boost.set(0,0,0);
+  rotation = HepRotation(*this);
+}
+
+double HepRotationZ::distance2( const HepRotationZ & r  ) const {
+  double answer = 2.0 * ( 1.0 - ( s * r.s + c * r.c ) ) ;
+  return (answer >= 0) ? answer : 0;
+}
+
+double HepRotationZ::distance2( const HepRotation & r  ) const {
+  double sum =    xx() * r.xx() + xy() * r.xy()
+                   + yx() * r.yx() + yy() * r.yy()
+						   + r.zz();
+  double answer = 3.0 - sum;
+  return (answer >= 0 ) ? answer : 0;
+}
+
+double HepRotationZ::distance2( const HepLorentzRotation & lt  ) const {
+  HepAxisAngle a; 
+  Hep3Vector   b;
+  lt.decompose(b, a);
+  double bet = b.beta();
+  double bet2 = bet*bet;
+  HepRotation r(a);
+  return bet2/(1-bet2) + distance2(r);
+}
+
+double HepRotationZ::distance2( const HepBoost & lt ) const {
+  return distance2( HepLorentzRotation(lt));
+}
+
+double HepRotationZ::howNear( const HepRotationZ & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationZ::howNear( const HepRotation & r ) const {
+  return sqrt(distance2(r));
+}
+double HepRotationZ::howNear( const HepBoost & lt ) const {
+  return sqrt(distance2(lt));
+}
+double HepRotationZ::howNear( const HepLorentzRotation & lt ) const {
+  return sqrt(distance2(lt));
+}
+bool HepRotationZ::isNear(const HepRotationZ & r,double epsilon)const {
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationZ::isNear(const HepRotation & r,double epsilon)const {
+  return (distance2(r) <= epsilon*epsilon);
+}
+bool HepRotationZ::isNear( const HepBoost & lt,double epsilon) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+bool HepRotationZ::isNear( const HepLorentzRotation & lt,
+                                     double epsilon) const {
+  return (distance2(lt) <= epsilon*epsilon);
+}
+
+double HepRotationZ::norm2() const {
+  return 2.0 - 2.0 * c;
+}
+
+std::ostream & HepRotationZ::print( std::ostream & os ) const {
+  os << "\nRotation about Z (" << d <<
+                ") [cos d = " << c << " sin d = " << s << "]\n";
+  return os;
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/SpaceVector.cc
===================================================================
--- trunk/CLHEP/src/SpaceVector.cc	(revision 4)
+++ trunk/CLHEP/src/SpaceVector.cc	(revision 4)
@@ -0,0 +1,313 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// SpaceVector
+//
+// This is the implementation of those methods of the Hep3Vector class which
+// originated from the ZOOM SpaceVector class.  Several groups of these methods
+// have been separated off into the following code units:
+//
+// SpaceVectorR.cc	All methods involving rotation
+// SpaceVectorD.cc	All methods involving angle decomposition
+// SpaceVectorP.cc	Intrinsic properties and methods involving second vector
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+//-*****************************
+//           - 1 -
+// set (multiple components)
+// in various coordinate systems
+//
+//-*****************************
+
+void Hep3Vector::setSpherical (
+		double r,
+                double theta,
+                double phi) {
+  if ( r < 0 ) {
+    ZMthrowC (ZMxpvNegativeR(
+      "Spherical coordinates set with negative   R"));
+    // No special return needed if warning is ignored.
+  }
+  if ( (theta < 0) || (theta > CLHEP::pi) ) {
+    ZMthrowC (ZMxpvUnusualTheta(
+      "Spherical coordinates set with theta not in [0, PI]"));
+	// No special return needed if warning is ignored.
+  }
+  dz = r * cos(theta);
+  double rho ( r*sin(theta));
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+  return;
+} /* setSpherical (r, theta, phi) */
+
+void Hep3Vector::setCylindrical (
+ 		double rho,
+                double phi,
+                double z) {
+  if ( rho < 0 ) {
+    ZMthrowC (ZMxpvNegativeR(
+      "Cylindrical coordinates supplied with negative Rho"));
+    // No special return needed if warning is ignored.
+  }
+  dz = z;
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+  return;
+} /* setCylindrical (r, phi, z) */
+
+void Hep3Vector::setRhoPhiTheta (
+ 		double rho,
+                double phi,
+                double theta) {
+  if (rho == 0) {
+    ZMthrowC (ZMxpvZeroVector(
+      "Attempt set vector components rho, phi, theta with zero rho -- "
+      "zero vector is returned, ignoring theta and phi"));
+    dx = 0; dy = 0; dz = 0;
+    return;
+  }
+  if ( (theta == 0) || (theta == CLHEP::pi) ) {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "Attempt set cylindrical vector vector with finite rho and "
+      "theta along the Z axis:  infinite Z would be computed"));
+  }
+  if ( (theta < 0) || (theta > CLHEP::pi) ) {
+    ZMthrowC (ZMxpvUnusualTheta(
+      "Rho, phi, theta set with theta not in [0, PI]"));
+	// No special return needed if warning is ignored.
+  }
+  dz = rho / tan (theta);
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+  return;
+} /* setCyl (rho, phi, theta) */
+
+void Hep3Vector::setRhoPhiEta (
+ 		double rho,
+                double phi,
+                double eta ) {
+  if (rho == 0) {
+    ZMthrowC (ZMxpvZeroVector(
+      "Attempt set vector components rho, phi, eta with zero rho -- "
+      "zero vector is returned, ignoring eta and phi"));
+    dx = 0; dy = 0; dz = 0;
+    return;
+  }
+  double theta (2 * atan ( exp (-eta) ));
+  dz = rho / tan (theta);
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+  return;
+} /* setCyl (rho, phi, eta) */
+
+
+
+//************
+//    - 3 - 
+// Comparisons
+//
+//************
+
+int Hep3Vector::compare (const Hep3Vector & v) const {
+  if       ( dz > v.dz ) {
+    return 1;
+  } else if ( dz < v.dz ) {
+    return -1;
+  } else if ( dy > v.dy ) {
+    return 1;
+  } else if ( dy < v.dy ) {
+    return -1;
+  } else if ( dx > v.dx ) {
+    return 1;
+  } else if ( dx < v.dx ) {
+    return -1;
+  } else {
+    return 0;
+  }
+} /* Compare */
+
+
+bool Hep3Vector::operator > (const Hep3Vector & v) const {
+	return (compare(v)  > 0);
+}
+bool Hep3Vector::operator < (const Hep3Vector & v) const {
+	return (compare(v)  < 0);
+}
+bool Hep3Vector::operator>= (const Hep3Vector & v) const {
+	return (compare(v) >= 0);
+}
+bool Hep3Vector::operator<= (const Hep3Vector & v) const {
+	return (compare(v) <= 0);
+}
+
+
+
+
+//-********
+// Nearness
+//-********
+
+// These methods all assume you can safely take mag2() of each vector.
+// Absolutely safe but slower and much uglier alternatives were 
+// provided as build-time options in ZOOM SpaceVectors.
+// Also, much smaller codes were provided tht assume you can square
+// mag2() of each vector; but those return bad answers without warning
+// when components exceed 10**90. 
+//
+// IsNear, HowNear, and DeltaR are found in ThreeVector.cc
+
+double Hep3Vector::howParallel (const Hep3Vector & v) const {
+  // | V1 x V2 | / | V1 dot V2 |
+  double v1v2 = fabs(dot(v));
+  if ( v1v2 == 0 ) {
+    // Zero is parallel to no other vector except for zero.
+    return ( (mag2() == 0) && (v.mag2() == 0) ) ? 0 : 1;
+  }
+  Hep3Vector v1Xv2 ( cross(v) );
+  double abscross = v1Xv2.mag();
+  if ( abscross >= v1v2 ) {
+    return 1;
+  } else {
+    return abscross/v1v2;
+  }
+} /* howParallel() */
+
+bool Hep3Vector::isParallel (const Hep3Vector & v,
+                              double epsilon) const {
+  // | V1 x V2 | **2  <= epsilon **2 | V1 dot V2 | **2
+  // V1 is *this, V2 is v
+
+  static const double TOOBIG = pow(2.0,507);
+  static const double SCALE  = pow(2.0,-507);
+  double v1v2 = fabs(dot(v));
+  if ( v1v2 == 0 ) {
+    return ( (mag2() == 0) && (v.mag2() == 0) );
+  }
+  if ( v1v2 >= TOOBIG ) {
+    Hep3Vector sv1 ( *this * SCALE );
+    Hep3Vector sv2 ( v * SCALE );
+    Hep3Vector sv1Xsv2 = sv1.cross(sv2);
+    double x2 = sv1Xsv2.mag2();
+    double limit = v1v2*SCALE*SCALE;
+    limit = epsilon*epsilon*limit*limit;
+    return ( x2 <= limit );
+  }
+
+  // At this point we know v1v2 can be squared.
+
+  Hep3Vector v1Xv2 ( cross(v) );
+  if (  (fabs (v1Xv2.dx) > TOOBIG) ||
+        (fabs (v1Xv2.dy) > TOOBIG) ||
+        (fabs (v1Xv2.dz) > TOOBIG) ) {
+    return false;
+  }
+                    
+  return ( (v1Xv2.mag2()) <= ((epsilon * v1v2) * (epsilon * v1v2)) );
+
+} /* isParallel() */
+
+
+double Hep3Vector::howOrthogonal (const Hep3Vector & v) const {
+  // | V1 dot V2 | / | V1 x V2 | 
+
+  double v1v2 = fabs(dot(v));
+	//-| Safe because both v1 and v2 can be squared
+  if ( v1v2 == 0 ) {
+    return 0;	// Even if one or both are 0, they are considered orthogonal
+  }
+  Hep3Vector v1Xv2 ( cross(v) );
+  double abscross = v1Xv2.mag();
+  if ( v1v2 >= abscross ) {
+    return 1;
+  } else {
+    return v1v2/abscross;
+  }
+
+} /* howOrthogonal() */
+
+bool Hep3Vector::isOrthogonal (const Hep3Vector & v,
+			     double epsilon) const {
+// | V1 x V2 | **2  <= epsilon **2 | V1 dot V2 | **2
+// V1 is *this, V2 is v
+
+  static const double TOOBIG = pow(2.0,507);
+  static const double SCALE = pow(2.0,-507);
+  double v1v2 = fabs(dot(v));
+        //-| Safe because both v1 and v2 can be squared
+  if ( v1v2 >= TOOBIG ) {
+    Hep3Vector sv1 ( *this * SCALE );
+    Hep3Vector sv2 ( v * SCALE );
+    Hep3Vector sv1Xsv2 = sv1.cross(sv2);
+    double x2 = sv1Xsv2.mag2();
+    double limit = epsilon*epsilon*x2;
+    double y2 = v1v2*SCALE*SCALE;
+    return ( y2*y2 <= limit );
+  }
+
+  // At this point we know v1v2 can be squared.
+
+  Hep3Vector eps_v1Xv2 ( cross(epsilon*v) );
+  if (  (fabs (eps_v1Xv2.dx) > TOOBIG) ||
+        (fabs (eps_v1Xv2.dy) > TOOBIG) ||
+        (fabs (eps_v1Xv2.dz) > TOOBIG) ) {
+    return true;
+  }
+
+  // At this point we know all the math we need can be done.
+
+  return ( v1v2*v1v2 <= eps_v1Xv2.mag2() );
+
+} /* isOrthogonal() */
+
+double Hep3Vector::setTolerance (double tol) {
+// Set the tolerance for Hep3Vectors to be considered near one another
+  double oldTolerance (tolerance);
+  tolerance = tol;
+  return oldTolerance;
+}
+
+
+
+//-***********************
+// Helper Methods:
+//	negativeInfinity()
+//-***********************
+
+double Hep3Vector::negativeInfinity() const {
+  // A byte-order-independent way to return -Infinity
+  struct Dib {
+    union {
+      double d;
+      unsigned char i[8];
+    } u;
+  };
+  Dib negOne;
+  Dib posTwo;
+  negOne.u.d = -1.0;
+  posTwo.u.d =  2.0;
+  Dib value;
+  int k;
+  for (k=0; k<8; k++) {
+    value.u.i[k] = negOne.u.i[k] | posTwo.u.i[k];
+  }
+  return value.u.d;
+}
+
+}  // namespace CLHEP
+
+
Index: trunk/CLHEP/src/SpaceVectorD.cc
===================================================================
--- trunk/CLHEP/src/SpaceVectorD.cc	(revision 4)
+++ trunk/CLHEP/src/SpaceVectorD.cc	(revision 4)
@@ -0,0 +1,78 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the subset of those methods of the Hep3Vector 
+// class which originated from the ZOOM SpaceVector class *and* which involve
+// the esoteric concepts of polar/azimuthal angular decomposition.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+//-*********************************************
+//			- 6 -
+// Decomposition of an angle between two vectors
+//
+//-*********************************************
+
+
+double Hep3Vector::polarAngle (const Hep3Vector & v2) const {
+  return fabs(v2.getTheta() - getTheta());
+} /* polarAngle */
+
+double Hep3Vector::polarAngle (const Hep3Vector & v2,
+				const Hep3Vector & ref) const {
+  return fabs( v2.angle(ref) - angle(ref) );
+} /* polarAngle (v2, ref) */
+
+// double Hep3Vector::azimAngle (const Hep3Vector & v2) const 
+// is now in the .icc file as deltaPhi(v2)
+
+double Hep3Vector::azimAngle  (const Hep3Vector & v2,
+				const Hep3Vector & ref) const {
+
+  Hep3Vector vperp ( perpPart(ref) );
+  if ( vperp.mag2() == 0 ) {
+    ZMthrowC (ZMxpvAmbiguousAngle(
+      "Cannot find azimuthal angle with reference direction parallel to "
+      "vector 1 -- will return zero"));
+   return 0;
+  }
+
+  Hep3Vector v2perp ( v2.perpPart(ref) );
+  if ( v2perp.mag2() == 0 ) {
+    ZMthrowC (ZMxpvAmbiguousAngle(
+      "Cannot find azimuthal angle with reference direction parallel to "
+      "vector 2 -- will return zero"));
+   return 0;
+  }
+
+  double ang = vperp.angle(v2perp);
+
+  // Now compute the sign of the answer:  that of U*(VxV2) or 
+  // the equivalent expression V*(V2xU).
+
+  if  ( dot(v2.cross(ref)) >= 0 ) {
+    return ang;
+  } else {
+    return -ang;
+  }
+
+	//-| Note that if V*(V2xU) is zero, we want to return 0 or PI
+	//-| depending on whether vperp is aligned or antialigned with v2perp.
+	//-| The computed angle() expression does this properly.
+
+} /* azimAngle (v2, ref) */
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/SpaceVectorP.cc
===================================================================
--- trunk/CLHEP/src/SpaceVectorP.cc	(revision 4)
+++ trunk/CLHEP/src/SpaceVectorP.cc	(revision 4)
@@ -0,0 +1,158 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// SpaceVector
+//
+// This is the implementation of the subset of those methods of the Hep3Vector 
+// class which originated from the ZOOM SpaceVector class *and* which involve
+// intrinsic properties or propeties relative to a second vector.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+#include <cmath>
+
+namespace CLHEP  {
+
+//-********************************
+//		- 5 -
+// Intrinsic properties of a vector
+// and properties relative to a direction
+//
+//-********************************
+
+double Hep3Vector::beta() const {
+  double b = sqrt(mag2());
+  if (b >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Beta taken for Hep3Vector of at least unit length"));
+  }
+  return b;
+}
+
+double Hep3Vector::gamma() const {
+  double beta = sqrt(mag2());
+  if (beta == 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Gamma taken for Hep3Vector of unit magnitude -- infinite result"));
+  }
+  if (beta > 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Gamma taken for Hep3Vector of more than unit magnitude -- "
+      "the sqrt function would return NAN" ));
+  }
+  return 1/sqrt(1-beta*beta);
+}
+
+double Hep3Vector::rapidity() const {
+  if (fabs(dz) == 1) {
+    ZMthrowC (ZMxpvTachyonic(
+      "Rapidity in Z direction taken for Hep3Vector with |Z| = 1 -- \n"
+      "the log should return infinity"));
+  }
+  if (fabs(dz) > 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Rapidity in Z direction taken for Hep3Vector with |Z| > 1 -- \n"
+      "the log would return a NAN" ));
+  }
+  // Want inverse tanh(dz):
+  return (.5 * log((1+dz)/(1-dz)) );
+}
+
+double Hep3Vector::coLinearRapidity() const {
+  double b = beta();
+  if (b == 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Co-linear Rapidity taken for Hep3Vector of unit length -- "
+      "the log should return infinity"));
+  }
+  if (b > 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Co-linear Rapidity taken for Hep3Vector of more than unit length -- "
+      "the log would return a NAN" ));
+  }
+  // Want inverse tanh(b):
+  return (.5 * log((1+b)/(1-b)) );
+}
+
+//-***********************************************
+// Other properties relative to a reference vector
+//-***********************************************
+
+Hep3Vector Hep3Vector::project (const Hep3Vector & v2) const {
+  double mag2v2 = v2.mag2();
+  if (mag2v2 == 0) {
+    ZMthrowA (ZMxpvZeroVector(
+      "Attempt to take projection of vector against zero reference vector "));
+    return project();
+  }
+  return ( v2 * (dot(v2)/mag2v2) );
+}
+
+double Hep3Vector::rapidity(const Hep3Vector & v2) const {
+  double vmag = v2.mag();
+  if ( vmag == 0 ) {
+    ZMthrowA (ZMxpvZeroVector(
+      "Rapidity taken with respect to zero vector" ));
+    return 0;    
+  }
+  double z = dot(v2)/vmag;
+  if (fabs(z) >= 1) {
+    ZMthrowA (ZMxpvTachyonic(
+      "Rapidity taken for too large a Hep3Vector "
+      "-- would return infinity or NAN"));
+  }
+  // Want inverse tanh(z):
+  return (.5 * log((1+z)/(1-z)) );
+}
+
+double Hep3Vector::eta(const Hep3Vector & v2) const {
+  // Defined as    -log ( tan ( .5* theta(u) ) );
+  //
+  // Quicker is to use cosTheta:
+  // tan (theta/2) = sin(theta)/(1 + cos(theta))
+
+  double r   = getR();
+  double v2r = v2.mag();
+  if ( (r == 0) || (v2r == 0) ) {
+    ZMthrowA (ZMxpvAmbiguousAngle(
+      "Cannot find pseudorapidity of a zero vector relative to a vector"));
+    return 0.;
+  }
+  double c  = dot(v2)/(r*v2r);
+  if ( c >= 1 ) {
+    c = 1; 	//-| We don't want to return NAN because of roundoff
+    ZMthrowC (ZMxpvInfinity(
+      "Pseudorapidity of vector relative to parallel vector -- "
+      "will give infinite result"));
+   			    // We can just go on; tangent will be 0, so
+			    // log (tangent) will be -INFINITY, so result
+			    // will be +INFINITY.
+  }
+  if ( c <= -1 ) {
+    ZMthrowC (ZMxpvInfinity(
+      "Pseudorapidity of vector relative to anti-parallel vector -- "
+      "will give negative infinite result"));
+    			//-| We don't want to return NAN because of roundoff
+    return ( negativeInfinity() );
+			    //  If we just went on, the tangent would be NAN
+			    //  so return would be NAN.  But the proper limit
+			    // of tan is +Infinity, so the return should be
+			    // -INFINITY.
+  }
+
+  double tangent = sqrt (1-c*c) / ( 1 + c );
+  return (- log (tangent));
+
+} /* eta (u) */
+
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/SpaceVectorR.cc
===================================================================
--- trunk/CLHEP/src/SpaceVectorR.cc	(revision 4)
+++ trunk/CLHEP/src/SpaceVectorR.cc	(revision 4)
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the subset of those methods of the Hep3Vector 
+// class which originated from the ZOOM SpaceVector class *and* which involve
+// the concepts of rotation.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/AxisAngle.h"
+#include "CLHEP/Vector/EulerAngles.h"
+#include "CLHEP/Vector/ZMxpv.h"
+
+namespace CLHEP  {
+
+//-************************
+// rotate about axis
+//-************************
+
+Hep3Vector & Hep3Vector::rotate (const Hep3Vector & axis,
+				   double delta) {
+  double r = axis.mag();
+  if ( r == 0 ) {
+    ZMthrowA (ZMxpvZeroVector(
+      "Attempt to rotate around a zero vector axis! "));
+    return *this;
+  }
+  register double scale=1.0/r;
+  register double ux = scale*axis.getX();
+  register double uy = scale*axis.getY();
+  register double uz = scale*axis.getZ();
+  double cd = cos(delta);
+  double sd = sin(delta);
+  register double ocd = 1 - cd;
+  double rx;
+  double ry;
+  double rz;
+
+  { register double  ocdux = ocd * ux;
+    rx = dx * ( cd + ocdux * ux           ) +
+         dy * (      ocdux * uy - sd * uz ) +
+         dz * (      ocdux * uz + sd * uy ) ;
+  }
+
+  { register double  ocduy = ocd * uy;
+    ry = dy * ( cd + ocduy * uy           ) +
+         dz * (      ocduy * uz - sd * ux ) +
+         dx * (      ocduy * ux + sd * uz ) ;
+  }
+
+  { register double  ocduz = ocd * uz;
+    rz = dz * ( cd + ocduz * uz           ) +
+         dx * (      ocduz * ux - sd * uy ) +
+         dy * (      ocduz * uy + sd * ux ) ;
+  }
+
+  dx = rx;
+  dy = ry;
+  dz = rz;
+
+  return *this;
+} /* rotate */
+
+
+
+//-****************************
+// rotate by three euler angles
+//-****************************
+
+
+Hep3Vector & Hep3Vector::rotate (double phi, 
+				 double theta, 
+				 double psi)  {
+
+  double rx;
+  double ry;
+  double rz;
+
+  register double sinPhi   = sin( phi   ), cosPhi   = cos( phi   );
+  register double sinTheta = sin( theta ), cosTheta = cos( theta );
+  register double sinPsi   = sin( psi   ), cosPsi   = cos( psi   );
+
+  rx = 	(cosPsi * cosPhi   - cosTheta * sinPsi * sinPhi)   * dx  +
+	(cosPsi * sinPhi   + cosTheta * sinPsi * cosPhi)   * dy  +
+  	(sinPsi * sinTheta)				   * dz  ;
+
+  ry = 	(- sinPsi * cosPhi - cosTheta * cosPsi * sinPhi)   * dx  +
+	(- sinPsi * sinPhi + cosTheta * cosPsi * cosPhi)   * dy  +
+  	(cosPsi * sinTheta)				   * dz  ;
+
+  rz = 	(sinTheta * sinPhi)				   * dx  +
+  	(- sinTheta * cosPhi)				   * dy  +
+	(cosTheta)					   * dz  ;
+
+  dx = rx;
+  dy = ry;
+  dz = rz;
+
+  return *this;
+
+} /* rotate */
+
+
+
+
+//-*******************
+// rotate(HepAxisAngle)
+// rotate(HepEulerAngles)
+//-*******************
+
+Hep3Vector & Hep3Vector::rotate (const HepAxisAngle & ax ) {
+  return rotate( ax.getAxis(), ax.delta() );
+}
+
+Hep3Vector & Hep3Vector::rotate (const HepEulerAngles & ex ) {
+  return rotate( ex.phi(), ex.theta(), ex.psi() );
+}
+
+
+//-***********************
+// rotationOf(HepAxisAngle)
+// rotationOf(HepEulerAngles)
+// and coordinate axis rotations
+//-***********************
+
+Hep3Vector rotationOf (const Hep3Vector & vec, const HepAxisAngle & ax) {
+  Hep3Vector vv(vec);
+  return vv.rotate (ax);
+}
+
+Hep3Vector rotationOf (const Hep3Vector & vec,
+                       const Hep3Vector & axis, double delta) {
+  Hep3Vector vv(vec);
+  return vv.rotate(axis, delta);
+}
+
+Hep3Vector rotationOf (const Hep3Vector & vec, const HepEulerAngles & ex) {
+  Hep3Vector vv(vec);
+  return vv.rotate (ex);
+}
+
+Hep3Vector rotationOf (const Hep3Vector & vec,
+                       double phi, double theta, double psi) {
+  Hep3Vector vv(vec);
+  return vv.rotate(phi, theta, psi);
+}
+
+Hep3Vector rotationXOf (const Hep3Vector & vec, double delta) {
+  Hep3Vector vv(vec);
+  return vv.rotateX (delta);
+}
+
+Hep3Vector rotationYOf (const Hep3Vector & vec, double delta) {
+  Hep3Vector vv(vec);
+  return vv.rotateY (delta);
+}
+
+Hep3Vector rotationZOf (const Hep3Vector & vec, double delta) {
+  Hep3Vector vv(vec);
+  return vv.rotateZ (delta);
+}
+
+}  // namespace CLHEP
+
Index: trunk/CLHEP/src/ThreeVector.cc
===================================================================
--- trunk/CLHEP/src/ThreeVector.cc	(revision 4)
+++ trunk/CLHEP/src/ThreeVector.cc	(revision 4)
@@ -0,0 +1,359 @@
+// -*- C++ -*-
+// $Id: ThreeVector.cc,v 1.1 2008-06-04 14:15:11 demin Exp $
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the Hep3Vector class.
+//
+// See also ThreeVectorR.cc for implementation of Hep3Vector methods which 
+// would couple in all the HepRotation methods.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+#include "CLHEP/Units/PhysicalConstants.h"
+
+#include <cmath>
+#include <iostream>
+
+namespace CLHEP  {
+
+void Hep3Vector::setMag(double ma) {
+  double factor = mag();
+  if (factor == 0) {
+    ZMthrowA ( ZMxpvZeroVector (
+    "Hep3Vector::setMag : zero vector can't be stretched"));
+  }else{
+    factor = ma/factor;
+    setX(x()*factor);
+    setY(y()*factor);
+    setZ(z()*factor);
+  }
+}
+
+double Hep3Vector::operator () (int i) const {
+  switch(i) {
+  case X:
+    return x();
+  case Y:
+    return y();
+  case Z:
+    return z();
+  default:
+    std::cerr << "Hep3Vector subscripting: bad index (" << i << ")"
+		 << std::endl;
+  }
+  return 0.;
+}
+
+double & Hep3Vector::operator () (int i) {
+  static double dummy;
+  switch(i) {
+  case X:
+    return dx;
+  case Y:
+    return dy;
+  case Z:
+    return dz;
+  default:
+    std::cerr
+      << "Hep3Vector subscripting: bad index (" << i << ")"
+      << std::endl;
+    return dummy;
+  }
+}
+
+Hep3Vector & Hep3Vector::rotateUz(const Hep3Vector& NewUzVector) {
+  // NewUzVector must be normalized !
+
+  double u1 = NewUzVector.x();
+  double u2 = NewUzVector.y();
+  double u3 = NewUzVector.z();
+  double up = u1*u1 + u2*u2;
+
+  if (up>0) {
+      up = sqrt(up);
+      double px = dx,  py = dy,  pz = dz;
+      dx = (u1*u3*px - u2*py)/up + u1*pz;
+      dy = (u2*u3*px + u1*py)/up + u2*pz;
+      dz =    -up*px +             u3*pz;
+    }
+  else if (u3 < 0.) { dx = -dx; dz = -dz; }      // phi=0  teta=pi
+  else {};
+  return *this;
+}
+
+double Hep3Vector::pseudoRapidity() const {
+  double m = mag();
+  if ( m==  0   ) return  0.0;   
+  if ( m==  z() ) return  1.0E72;
+  if ( m== -z() ) return -1.0E72;
+  return 0.5*log( (m+z())/(m-z()) );
+}
+
+std::ostream & operator<< (std::ostream & os, const Hep3Vector & v) {
+  return os << "(" << v.x() << "," << v.y() << "," << v.z() << ")";
+}
+
+void ZMinput3doubles ( std::istream & is, const char * type,
+                       double & x, double & y, double & z );
+
+std::istream & operator>>(std::istream & is, Hep3Vector & v) {
+  double x, y, z;
+  ZMinput3doubles ( is, "Hep3Vector", x, y, z );
+  v.set(x, y, z);
+  return  is;
+}  // operator>>()
+
+const Hep3Vector HepXHat(1.0, 0.0, 0.0);
+const Hep3Vector HepYHat(0.0, 1.0, 0.0);
+const Hep3Vector HepZHat(0.0, 0.0, 1.0);
+
+//-------------------
+//
+// New methods introduced when ZOOM PhysicsVectors was merged in:
+//
+//-------------------
+
+Hep3Vector & Hep3Vector::rotateX (double phi) {
+  double sinphi = sin(phi);
+  double cosphi = cos(phi);
+  double ty;
+  ty = dy * cosphi - dz * sinphi;
+  dz = dz * cosphi + dy * sinphi;
+  dy = ty;
+  return *this;
+} /* rotateX */
+
+Hep3Vector & Hep3Vector::rotateY (double phi) {
+  double sinphi = sin(phi);
+  double cosphi = cos(phi);
+  double tz;
+  tz = dz * cosphi - dx * sinphi;
+  dx = dx * cosphi + dz * sinphi;
+  dz = tz;
+  return *this;
+} /* rotateY */
+
+Hep3Vector & Hep3Vector::rotateZ (double phi) {
+  double sinphi = sin(phi);
+  double cosphi = cos(phi);
+  double tx;
+  tx = dx * cosphi - dy * sinphi;
+  dy = dy * cosphi + dx * sinphi;
+  dx = tx;
+  return *this;
+} /* rotateZ */
+
+bool Hep3Vector::isNear(const Hep3Vector & v, double epsilon) const {
+  double limit = dot(v)*epsilon*epsilon;
+  return ( (*this - v).mag2() <= limit );
+} /* isNear() */
+
+double Hep3Vector::howNear(const Hep3Vector & v ) const {
+  // | V1 - V2 | **2  / V1 dot V2, up to 1
+  double d   = (*this - v).mag2();
+  double vdv = dot(v);
+  if ( (vdv > 0) && (d < vdv)  ) {
+    return sqrt (d/vdv);
+  } else if ( (vdv == 0) && (d == 0) ) {
+    return 0;
+  } else {
+    return 1;
+  }
+} /* howNear */
+
+double Hep3Vector::deltaPhi  (const Hep3Vector & v2) const {
+  double dphi = v2.getPhi() - getPhi();
+  if ( dphi > CLHEP::pi ) {
+    dphi -= CLHEP::twopi;
+  } else if ( dphi <= -CLHEP::pi ) {
+    dphi += CLHEP::twopi;
+  }
+  return dphi;
+} /* deltaPhi */
+
+double Hep3Vector::deltaR ( const Hep3Vector & v ) const {
+  double a = eta() - v.eta();
+  double b = deltaPhi(v); 
+  return sqrt ( a*a + b*b );
+} /* deltaR */
+
+double Hep3Vector::cosTheta(const Hep3Vector & q) const {
+  double arg;
+  double ptot2 = mag2()*q.mag2();
+  if(ptot2 <= 0) {
+    arg = 0.0;
+  }else{
+    arg = dot(q)/sqrt(ptot2);
+    if(arg >  1.0) arg =  1.0;
+    if(arg < -1.0) arg = -1.0;
+  }
+  return arg;
+}
+
+double Hep3Vector::cos2Theta(const Hep3Vector & q) const {
+  double arg;
+  double ptot2 = mag2();
+  double qtot2 = q.mag2();
+  if ( ptot2 == 0 || qtot2 == 0 )  {
+    arg = 1.0;
+  }else{
+    double pdq = dot(q);
+    arg = (pdq/ptot2) * (pdq/qtot2);
+        // More naive methods overflow on vectors which can be squared
+        // but can't be raised to the 4th power.
+    if(arg >  1.0) arg =  1.0;
+ }
+ return arg;
+}
+
+void Hep3Vector::setEta (double eta) {
+  double phi = 0;
+  double r;
+  if ( (dx == 0) && (dy == 0) ) {
+    if (dz == 0) {
+      ZMthrowC (ZMxpvZeroVector(
+        "Attempt to set eta of zero vector -- vector is unchanged"));
+      return;
+    }
+    ZMthrowC (ZMxpvZeroVector(
+      "Attempt to set eta of vector along Z axis -- will use phi = 0"));
+    r = fabs(dz);
+  } else {
+    r = getR();
+    phi = getPhi();
+  }
+  double tanHalfTheta = exp ( -eta );
+  double cosTheta =
+        (1 - tanHalfTheta*tanHalfTheta) / (1 + tanHalfTheta*tanHalfTheta);
+  dz = r * cosTheta;
+  double rho = r*sqrt(1 - cosTheta*cosTheta);
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+  return;
+}
+
+void Hep3Vector::setCylTheta (double theta) {
+
+  // In cylindrical coords, set theta while keeping rho and phi fixed
+
+  if ( (dx == 0) && (dy == 0) ) {
+    if (dz == 0) {
+      ZMthrowC (ZMxpvZeroVector(
+        "Attempt to set cylTheta of zero vector -- vector is unchanged"));
+      return;
+    }
+    if (theta == 0) {
+      dz = fabs(dz);
+      return;
+    }
+    if (theta == CLHEP::pi) {
+      dz = -fabs(dz);
+      return;
+    }
+    ZMthrowC (ZMxpvZeroVector(
+      "Attempt set cylindrical theta of vector along Z axis "
+      "to a non-trivial value, while keeping rho fixed -- "
+      "will return zero vector"));
+    dz = 0;
+    return;
+  }
+  if ( (theta < 0) || (theta > CLHEP::pi) ) {
+    ZMthrowC (ZMxpvUnusualTheta(
+      "Setting Cyl theta of a vector based on a value not in [0, PI]"));
+        // No special return needed if warning is ignored.
+  }
+  double phi (getPhi());
+  double rho = getRho();
+  if ( (theta == 0) || (theta == CLHEP::pi) ) {
+    ZMthrowC (ZMxpvInfiniteVector(
+      "Attempt to set cylindrical theta to 0 or PI "
+      "while keeping rho fixed -- infinite Z will be computed"));
+      dz = (theta==0) ? 1.0E72 : -1.0E72;
+    return;
+  }
+  dz = rho / tan (theta);
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+
+} /* setCylTheta */
+
+void Hep3Vector::setCylEta (double eta) {
+
+  // In cylindrical coords, set eta while keeping rho and phi fixed
+
+  double theta = 2 * atan ( exp (-eta) );
+
+        //-| The remaining code is similar to setCylTheta,  The reason for
+        //-| using a copy is so as to be able to change the messages in the
+        //-| ZMthrows to say eta rather than theta.  Besides, we assumedly
+        //-| need not check for theta of 0 or PI.
+
+  if ( (dx == 0) && (dy == 0) ) {
+    if (dz == 0) {
+      ZMthrowC (ZMxpvZeroVector(
+        "Attempt to set cylEta of zero vector -- vector is unchanged"));
+      return;
+    }
+    if (theta == 0) {
+      dz = fabs(dz);
+      return;
+    }
+    if (theta == CLHEP::pi) {
+      dz = -fabs(dz);
+      return;
+    }
+    ZMthrowC (ZMxpvZeroVector(
+      "Attempt set cylindrical eta of vector along Z axis "
+      "to a non-trivial value, while keeping rho fixed -- "
+      "will return zero vector"));
+    dz = 0;
+    return;
+  }
+  double phi (getPhi());
+  double rho = getRho();
+  dz = rho / tan (theta);
+  dy = rho * sin (phi);
+  dx = rho * cos (phi);
+
+} /* setCylEta */
+
+
+Hep3Vector operator/  ( const Hep3Vector & v1, double c ) {
+  if (c == 0) {
+    ZMthrowA ( ZMxpvInfiniteVector (
+      "Attempt to divide vector by 0 -- "
+      "will produce infinities and/or NANs"));
+  } 
+  double   oneOverC = 1.0/c;
+  return Hep3Vector  (  v1.x() * oneOverC,
+                        v1.y() * oneOverC,
+                        v1.z() * oneOverC );
+} /* v / c */
+
+Hep3Vector & Hep3Vector::operator/= (double c) {
+  if (c == 0) {
+    ZMthrowA (ZMxpvInfiniteVector(
+      "Attempt to do vector /= 0 -- "
+      "division by zero would produce infinite or NAN components"));
+  }
+  double oneOverC = 1.0/c;
+  dx *= oneOverC;
+  dy *= oneOverC;
+  dz *= oneOverC;
+  return *this;
+}
+
+double Hep3Vector::tolerance = Hep3Vector::ToleranceTicks * 2.22045e-16;
+
+}  // namespace CLHEP
+
+
+
Index: trunk/CLHEP/src/ThreeVectorR.cc
===================================================================
--- trunk/CLHEP/src/ThreeVectorR.cc	(revision 4)
+++ trunk/CLHEP/src/ThreeVectorR.cc	(revision 4)
@@ -0,0 +1,36 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of those methods of the Hep3Vector class which
+// require linking of the HepRotation class.  These methods have been broken 
+// out of ThreeVector.cc.
+//
+
+#ifdef GNUPRAGMA
+#pragma implementation
+#endif
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/ThreeVector.h"
+#include "CLHEP/Vector/Rotation.h"
+
+namespace CLHEP  {
+
+Hep3Vector & Hep3Vector::operator *= (const HepRotation & m) {
+  return *this = m * (*this);
+}
+
+Hep3Vector & Hep3Vector::transform(const HepRotation & m) {
+  return *this = m * (*this);
+}
+
+Hep3Vector & Hep3Vector::rotate(double angle, const Hep3Vector & axis){
+  HepRotation trans;
+  trans.rotate(angle, axis);
+  operator*=(trans);
+  return *this;
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/TwoVector.cc
===================================================================
--- trunk/CLHEP/src/TwoVector.cc	(revision 4)
+++ trunk/CLHEP/src/TwoVector.cc	(revision 4)
@@ -0,0 +1,187 @@
+// -*- C++ -*-
+// ---------------------------------------------------------------------------
+//
+// This file is a part of the CLHEP - a Class Library for High Energy Physics.
+//
+// This is the implementation of the Hep2Vector class.
+//
+//-------------------------------------------------------------
+
+#include "CLHEP/Vector/defs.h"
+#include "CLHEP/Vector/TwoVector.h"
+#include "CLHEP/Vector/ZMxpv.h"
+#include "CLHEP/Vector/ThreeVector.h"
+
+#include <cmath>
+#include <iostream>
+
+namespace CLHEP  {
+
+double Hep2Vector::tolerance = Hep2Vector::ZMpvToleranceTicks * 2.22045e-16;
+
+double Hep2Vector::setTolerance (double tol) {
+// Set the tolerance for Hep2Vectors to be considered near one another
+  double oldTolerance (tolerance);
+  tolerance = tol;
+  return oldTolerance;
+}
+
+double Hep2Vector::operator () (int i) const {
+  if (i == 0) {
+    return x();
+  }else if (i == 1) {
+    return y();
+  }else{
+    ZMthrowA(ZMxpvIndexRange(
+	"Hep2Vector::operator(): bad index"));
+    return 0.0;
+  }
+}
+
+double & Hep2Vector::operator () (int i) {
+  static double dummy;
+  switch(i) {
+  case X:
+    return dx;
+  case Y:
+    return dy;
+  default:
+    ZMthrowA (ZMxpvIndexRange(
+	"Hep2Vector::operator() : bad index"));
+    return dummy;
+  }
+}
+
+void Hep2Vector::rotate(double angle) {
+  double s = sin(angle);
+  double c = cos(angle);
+  double xx = dx;
+  dx = c*xx - s*dy;
+  dy = s*xx + c*dy;
+}
+
+Hep2Vector operator/ (const Hep2Vector & p, double a) {
+  if (a==0) {
+    ZMthrowA(ZMxpvInfiniteVector( "Division of Hep2Vector by zero"));
+  }
+  return Hep2Vector(p.x()/a, p.y()/a);
+}
+
+std::ostream & operator << (std::ostream & os, const Hep2Vector & q) {
+  os << "(" << q.x() << ", " << q.y() << ")";
+  return os;
+}
+
+void ZMinput2doubles ( std::istream & is, const char * type,
+                       double & x, double & y );
+
+std::istream & operator>>(std::istream & is, Hep2Vector & p) {
+  double x, y;
+  ZMinput2doubles ( is, "Hep2Vector", x, y );
+  p.set(x, y);
+  return  is;
+}  // operator>>()
+
+Hep2Vector::operator Hep3Vector () const {
+  return Hep3Vector ( dx, dy, 0.0 );
+}
+
+int Hep2Vector::compare (const Hep2Vector & v) const {
+  if       ( dy > v.dy ) {
+    return 1;
+  } else if ( dy < v.dy ) {
+    return -1;
+  } else if ( dx > v.dx ) {
+    return 1;
+  } else if ( dx < v.dx ) {
+    return -1;
+  } else {
+    return 0;
+  }
+} /* Compare */
+
+
+bool Hep2Vector::operator > (const Hep2Vector & v) const {
+	return (compare(v)  > 0);
+}
+bool Hep2Vector::operator < (const Hep2Vector & v) const {
+	return (compare(v)  < 0);
+}
+bool Hep2Vector::operator>= (const Hep2Vector & v) const {
+	return (compare(v) >= 0);
+}
+bool Hep2Vector::operator<= (const Hep2Vector & v) const {
+	return (compare(v) <= 0);
+}
+
+bool Hep2Vector::isNear(const Hep2Vector & p, double epsilon) const {
+  double limit = dot(p)*epsilon*epsilon;
+  return ( (*this - p).mag2() <= limit );
+} /* isNear() */
+
+double Hep2Vector::howNear(const Hep2Vector & p ) const {
+  double d   = (*this - p).mag2();
+  double pdp = dot(p);
+  if ( (pdp > 0) && (d < pdp)  ) {
+    return sqrt (d/pdp);
+  } else if ( (pdp == 0) && (d == 0) ) {
+    return 0;
+  } else {
+    return 1;
+  }
+} /* howNear */
+
+double Hep2Vector::howParallel (const Hep2Vector & v) const {
+  // | V1 x V2 | / | V1 dot V2 |
+  // Of course, the "cross product" is fictitious but the math is valid
+  double v1v2 = fabs(dot(v));
+  if ( v1v2 == 0 ) {
+    // Zero is parallel to no other vector except for zero.
+    return ( (mag2() == 0) && (v.mag2() == 0) ) ? 0 : 1;
+  }
+  double abscross = fabs ( dx * v.y() - dy - v.x() );
+  if ( abscross >= v1v2 ) {
+    return 1;
+  } else {
+    return abscross/v1v2;
+  }
+} /* howParallel() */
+
+bool Hep2Vector::isParallel (const Hep2Vector & v,
+			     double epsilon) const {
+  // | V1 x V2 | <= epsilon * | V1 dot V2 | 
+  // Of course, the "cross product" is fictitious but the math is valid
+  double v1v2 = fabs(dot(v));
+  if ( v1v2 == 0 ) {
+    // Zero is parallel to no other vector except for zero.
+    return ( (mag2() == 0) && (v.mag2() == 0) );
+  }
+  double abscross = fabs ( dx * v.y() - dy - v.x() );
+  return ( abscross <= epsilon * v1v2 );
+} /* isParallel() */
+
+double Hep2Vector::howOrthogonal (const Hep2Vector & v) const {
+  // | V1 dot V2 | / | V1 x V2 | 
+  // Of course, the "cross product" is fictitious but the math is valid
+  double v1v2 = fabs(dot(v));
+  if ( v1v2 == 0 ) {
+    return 0;	// Even if one or both are 0, they are considered orthogonal
+  }
+  double abscross = fabs ( dx * v.y() - dy - v.x() );
+  if ( v1v2 >= abscross ) {
+    return 1;
+  } else {
+    return v1v2/abscross;
+  }
+} /* howOrthogonal() */
+
+bool Hep2Vector::isOrthogonal (const Hep2Vector & v,
+			     double epsilon) const {
+  // | V1 dot V2 | <= epsilon * | V1 x V2 | 
+  // Of course, the "cross product" is fictitious but the math is valid
+  double v1v2 = fabs(dot(v));
+  double abscross = fabs ( dx * v.y() - dy - v.x() );
+  return ( v1v2 <= epsilon * abscross );
+} /* isOrthogonal() */
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/ZMinput.cc
===================================================================
--- trunk/CLHEP/src/ZMinput.cc	(revision 4)
+++ trunk/CLHEP/src/ZMinput.cc	(revision 4)
@@ -0,0 +1,333 @@
+#include "CLHEP/Vector/defs.h"
+
+#include <cctype>
+#include <iostream>
+
+namespace {
+
+bool eatwhitespace ( std::istream & is ) {
+  // Will discard whitespace until it either encounters EOF or bad input
+  // (in which case it will return false) or it hits a non-whitespace.  
+  // Will put that non whitespace character back so that after this routine
+  // returns true, is.get(c) should always work.
+  // If eatwhitespace returns false, is will always be in a fail or bad state.
+  char c;
+  bool avail = false;	// avail stays false until we know there is a nonwhite
+			// character available.
+  while ( is.get(c) ) {
+    if ( !isspace(c) ) {
+      is.putback(c);
+      avail = true;
+      break;
+    }
+  }
+  return avail;
+}
+
+void fouledup() {
+  std::cerr << "istream mysteriously lost a putback character!\n";
+}
+
+
+} // end of unnamed namespace
+
+
+namespace CLHEP  {
+
+
+void ZMinput3doubles ( std::istream & is, const char * type,
+			double & x, double & y, double & z ) {
+
+// Accepted formats are 
+// x y z
+// x, y, z (each comma is optional, and whitespace ignored if comma present)
+// ( x, y, z ) (commas optional)
+
+  char c;
+  bool parenthesis = false;
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before trying to input " << type << "\n";
+    return;
+  }
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == '(' ) {
+    parenthesis = true;
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended after ( trying to input " << type << "\n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }  
+
+  // At this point, parenthesis or not, the next item read is supposed to
+  // be the number x.
+
+  if (!(is >> x)) {
+    std::cerr << "Could not read first value in input of " << type << "\n";
+    return;
+  }
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before second value of " << type << "\n";
+    return;
+  } 
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == ',' ) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended ater one value and comma in " 
+							<< type << "\n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }
+
+  // At this point, comma or not, the next item read is supposed to
+  // be the number y.
+
+  if (!(is >> y)) {
+    std::cerr << "Could not read second value in input of " << type << "\n";
+    return;
+  }
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before third value of " << type << "\n";
+    return;
+  } 
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == ',' ) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended ater two values and comma in " 
+							<< type << "\n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }
+
+  // At this point, comma or not, the next item read is supposed to
+  // be the number z.
+
+  if (!(is >> z)) {
+    std::cerr << "Could not read third value in input of " << type << "\n";
+    return;
+  }
+
+  // Finally, check for the closing parenthesis if there was an open paren.
+
+  if (parenthesis) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "No closing parenthesis in input of " << type << "\n";
+      return;
+    } 
+    if ( !is.get(c) ) { fouledup(); return; }
+    if ( c != ')' ) {
+      std::cerr << "Missing closing parenthesis in input of " 
+							<< type << "\n";
+      // Now a trick to do (as nearly as we can) what 
+      // is.putback(c); is.setstate(std::ios_base::failbit); 
+      // would do (because using ios_base will confuse old CLHEP compilers):
+      if ( isdigit(c) || (c=='-') || (c=='+') ) {
+        is.putback('@');
+      } else {
+        is.putback('c');
+      }
+      int m;
+      is >> m;  // This fails, leaving the state bad, and the istream
+		// otherwise unchanged, except if the next char might
+		// have started a valid int, it turns to @
+      return;
+    }
+  }
+
+  return;
+
+}
+
+
+
+void ZMinputAxisAngle ( std::istream & is, 
+			double & x, double & y, double & z, 
+			double & delta ) {
+// Accepted formats are 
+// parenthesis optional, then
+// any acceptable format for a Hep3Vector, then
+// optional comma, then
+// delta, then
+// close parenthesis if opened at start.
+//
+// But if there is an open parenthesis, it must be for the overall
+// object.  That is, if the axis has parentheses, the form must be 
+// ( (x,y,z) , delta ) 
+
+  char c;
+  bool parenthesis = false;
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before trying to input AxisAngle \n";
+    return;
+  }
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == '(' ) {
+    parenthesis = true;
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended after ( trying to input AxisAngle \n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }  
+
+  // At this point, parenthesis or not, the next item read is supposed to
+  // be a valid Hep3Vector axis.
+
+  ZMinput3doubles ( is, "axis of AxisAngle", x, y, z );
+  if (!is) return;
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before delta of AxisAngle \n";
+    return;
+  } 
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == ',' ) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended ater axis and comma in AxisAngle \n"; 
+      return;
+    }
+  } else {
+    is.putback(c);
+  }
+
+  // At this point, comma or not, the next item read is supposed to
+  // be the number delta.
+
+  if (!(is >> delta)) {
+    std::cerr << "Could not delta value in input of AxisAngle \n";
+    return;
+  }
+
+  // Finally, check for the closing parenthesis if there was an open paren.
+
+  if (parenthesis) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "No closing parenthesis in input of AxisAngle \n";
+      return;
+    } 
+    if ( !is.get(c) ) { fouledup(); return; }
+    if ( c != ')' ) {
+      std::cerr << "Missing closing parenthesis in input of AxisAngle \n";
+      if ( isdigit(c) || (c=='-') || (c=='+') ) {
+        is.putback('@');
+      } else {
+        is.putback('c');
+      }
+      int m;
+      is >> m;  // This fails, leaving the state bad.
+      return;
+    }
+  }
+
+  return;
+
+}
+
+
+
+void ZMinput2doubles ( std::istream & is, const char * type,
+			double & x, double & y ) {
+
+// Accepted formats are 
+// x y 
+// x, y (comma is optional, and whitespace ignored if comma present)
+// ( x, y ) (comma optional)
+
+  char c;
+  bool parenthesis = false;
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before trying to input " << type << "\n";
+    return;
+  }
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == '(' ) {
+    parenthesis = true;
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended after ( trying to input " << type << "\n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }  
+
+  // At this point, parenthesis or not, the next item read is supposed to
+  // be the number x.
+
+  if (!(is >> x)) {
+    std::cerr << "Could not read first value in input of " << type << "\n";
+    return;
+  }
+
+  if ( !eatwhitespace(is) ) {
+    std::cerr << "istream ended before second value of " << type << "\n";
+    return;
+  } 
+
+  if ( !is.get(c) ) { fouledup(); return; }
+  if ( c == ',' ) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "istream ended ater one value and comma in " 
+							<< type << "\n";
+      return;
+    }
+  } else {
+    is.putback(c);
+  }
+
+  // At this point, comma or not, the next item read is supposed to
+  // be the number y.
+
+  if (!(is >> y)) {
+    std::cerr << "Could not read second value in input of " << type << "\n";
+    return;
+  }
+
+  // Finally, check for the closing parenthesis if there was an open paren.
+
+  if (parenthesis) {
+    if ( !eatwhitespace(is) ) {
+      std::cerr << "No closing parenthesis in input of " << type << "\n";
+      return;
+    } 
+    if ( !is.get(c) ) { fouledup(); return; }
+    if ( c != ')' ) {
+      std::cerr << "Missing closing parenthesis in input of " 
+							<< type << "\n";
+      // Now a trick to do (as nearly as we can) what 
+      // is.putback(c); is.setstate(std::ios_base::failbit); 
+      // would do (because using ios_base will confuse old CLHEP compilers):
+      if ( isdigit(c) || (c=='-') || (c=='+') ) {
+        is.putback('@');
+      } else {
+        is.putback('c');
+      }
+      int m;
+      is >> m;  // This fails, leaving the state bad, and the istream
+		// otherwise unchanged, except if the next char might
+		// have started a valid int, it turns to @
+      return;
+    }
+  }
+
+  return;
+
+}
+
+}  // namespace CLHEP
Index: trunk/CLHEP/src/ZMxpv.cc
===================================================================
--- trunk/CLHEP/src/ZMxpv.cc	(revision 4)
+++ trunk/CLHEP/src/ZMxpv.cc	(revision 4)
@@ -0,0 +1,190 @@
+// ----------------------------------------------------------------------
+//
+//  ZMxpv.cc   	Support for Vector package in the ZOOM context, where
+//		probelmatic conditions are handled via ZOOM Exceptions.
+//
+//		In the CLHEP context (that is, unless ENABLE_ZOOM_EXCEPTIONS
+//		is defined) this file is content-free.
+//
+//		ZMexception's are ZMthrown by classes in the PhysicsVectors
+//		package.  (To avoid name clashes, these start with ZMxpv.)
+//		Each possible such exception must be provided with some
+//		defining properties:  thowe are in this file.
+//
+// History:
+//   19-Nov-1997  MF    Initial version, to enable the ZMthrow exceptions
+//			in SpaceVector.
+//   15-Jun-1998  WEB	Added namespace support
+//   08-Jan-2001  MF	Moved into CLHEP
+//   09-Oct-2003  MF    Major addition:  Exception class defs for CLHEP case
+//
+// ----------------------------------------------------------------------
+
+
+#include "CLHEP/Vector/ZMxpv.h"
+
+#ifndef ENABLE_ZOOM_EXCEPTIONS
+
+CLHEP_vector_exception::CLHEP_vector_exception 
+		( const std::string & s ) throw() : message(s) {}		
+
+const char* 
+CLHEP_vector_exception::what() const throw() { 
+  static std::string answer;
+  answer  = name();
+  answer += ": ";
+  answer += message;  
+  return answer.c_str(); 
+}
+
+#define CLHEP_vector_exception_methods(NAME)				    \
+  NAME::NAME(const std::string & s) throw() : CLHEP_vector_exception(s) {}  \
+  const char* NAME::name() const throw() {				    \
+    return #NAME;							    \
+  }
+
+CLHEP_vector_exception_methods( ZMxPhysicsVectors )
+CLHEP_vector_exception_methods( ZMxpvSpacelike )
+CLHEP_vector_exception_methods( ZMxpvNegativeMass )
+CLHEP_vector_exception_methods( ZMxpvVectorInputFails )
+CLHEP_vector_exception_methods( ZMxpvIndexRange )
+CLHEP_vector_exception_methods( ZMxpvFixedAxis )
+
+CLHEP_vector_exception_methods( ZMxpvTachyonic )
+CLHEP_vector_exception_methods( ZMxpvZeroVector )
+CLHEP_vector_exception_methods( ZMxpvImproperTransformation )
+CLHEP_vector_exception_methods( ZMxpvInfiniteVector )
+CLHEP_vector_exception_methods( ZMxpvInfinity )
+CLHEP_vector_exception_methods( ZMxpvImproperRotation )
+CLHEP_vector_exception_methods( ZMxpvAmbiguousAngle )
+
+CLHEP_vector_exception_methods( ZMxpvNegativeR )
+CLHEP_vector_exception_methods( ZMxpvUnusualTheta )
+CLHEP_vector_exception_methods( ZMxpvParallelCols )
+CLHEP_vector_exception_methods( ZMxpvNotOrthogonal )
+CLHEP_vector_exception_methods( ZMxpvNotSymplectic )
+
+#endif // endif for ifndef ENABLE_ZOOM_EXCEPTIONS 
+
+// ========================================================================
+// ========================================================================
+// ========================================================================
+
+#ifdef ENABLE_ZOOM_EXCEPTIONS
+
+ZM_BEGIN_NAMESPACE( zmpv )	/*  namespace zmpv  {  */
+
+
+ZMexClassInfo ZMxPhysicsVectors::_classInfo (
+	"ZMxPhysicsVectors",
+	"PhysicsVectors",
+	ZMexSEVERE );
+// General Exception in a PhysicsVectors routine
+
+ZMexClassInfo ZMxpvInfiniteVector::_classInfo (
+	"InfiniteVector",
+	"PhysicsVectors",
+	ZMexERROR );
+// Infinite vector component
+
+ZMexClassInfo ZMxpvZeroVector::_classInfo (
+	"ZeroVector",
+	"PhysicsVectors",
+	ZMexERROR );
+// Zero Vector cannot be converted to Unit Vector
+
+ZMexClassInfo ZMxpvTachyonic::_classInfo (
+	"Tachyonic",
+	"PhysicsVectors",
+	ZMexERROR );
+// Relativistic method using vector representing speed greater than light
+
+ZMexClassInfo ZMxpvSpacelike::_classInfo (
+	"Spacelike",
+	"PhysicsVectors",
+	ZMexERROR );
+// Spacelike 4-vector used in context where rest mass or gamma needs computing
+
+ZMexClassInfo ZMxpvInfinity::_classInfo (
+	"Infinity",
+	"PhysicsVectors",
+	ZMexERROR );
+// Mathematical operation will lead to infinity as a Scalar result
+
+ZMexClassInfo ZMxpvNegativeMass::_classInfo (
+	"NegativeMass",
+	"PhysicsVectors",
+	ZMexERROR );
+// Kinematic operation was rendered meaningless by an input with negative t
+
+ZMexClassInfo ZMxpvAmbiguousAngle::_classInfo (
+	"AmbiguousAngle",
+	"PhysicsVectors",
+	ZMexWARNING );
+// Angle requested ill-defined, due to null or collinear vectors
+
+ZMexClassInfo ZMxpvNegativeR::_classInfo (
+	"NegativeR",
+	"PhysicsVectors",
+	ZMexWARNING );
+// Negative value supplied for vector magnitude
+
+ZMexClassInfo ZMxpvUnusualTheta::_classInfo (
+	"UnusualTheta",
+	"PhysicsVectors",
+	ZMexWARNING );
+// Theta supplied for polar coordinates outside of [0,PI]
+
+ZMexClassInfo ZMxpvVectorInputFails::_classInfo (
+	"VectorInputFails",
+	"PhysicsVectors",
+	ZMexERROR );
+// Theta supplied for polar coordinates outside of [0,PI]
+
+ZMexClassInfo ZMxpvParallelCols::_classInfo (
+	"ParallelCols",
+	"PhysicsVectors",
+	ZMexERROR );
+// Col's supplied to form a Rotation are parallel instead of orthogonal
+
+ZMexClassInfo ZMxpvImproperRotation::_classInfo (
+	"ImproperRotation",
+	"PhysicsVectors",
+	ZMexERROR );
+// Col's supplied to form a Rotation form a (rotation+reflection) instead
+
+ZMexClassInfo ZMxpvImproperTransformation::_classInfo (
+	"ImproperRotation",
+	"PhysicsVectors",
+	ZMexERROR );
+// Rows supplied to form a LorentzTransformation form tachyonic or reflection
+
+ZMexClassInfo ZMxpvNotOrthogonal::_classInfo (
+	"NotOrthogonal",
+	"PhysicsVectors",
+	ZMexWARNING );
+// Col's supplied to form a Rotation or LorentzTransformation are not orthogonal
+
+ZMexClassInfo ZMxpvNotSymplectic::_classInfo (
+	"NotSymplectic",
+	"PhysicsVectors",
+	ZMexWARNING );
+// A row supplied as part of a LorentzTransformation has wrong restmass()
+
+
+ZMexClassInfo ZMxpvFixedAxis::_classInfo (
+	"FixedAxis",
+	"PhysicsVectors",
+	ZMexERROR );
+// An attempt to change the axis is of a rotation fixed to be about X Y or Z.
+
+ZMexClassInfo ZMxpvIndexRange::_classInfo (
+	"IndexRange",
+	"PhysicsVectors",
+	ZMexERROR );
+// An attempt to access a vector in the p(i) notation, where i is out of range.
+
+
+ZM_END_NAMESPACE( zmpv )	/*  }  // namespace zmpv  */
+
+#endif  // endif for ifdef ENAMBLE_ZOOM_EXCEPTIONS
Index: trunk/doc/README
===================================================================
--- trunk/doc/README	(revision 4)
+++ trunk/doc/README	(revision 4)
@@ -0,0 +1,169 @@
+
+Using ExRootAnalysis package for PGS data analysis
+==================================================
+
+
+Author: Pavel Demin
+
+
+
+
+Introductory remarks
+====================
+
+
+The ExRootAnalysis is a package designed to simplify ROOT tree production and
+analysis. The purpose of this tutorial is to present current functionality of
+this software.
+
+
+
+
+Quick start with ExRootAnalysis
+===============================
+
+Make sure that ROOT is installed and ROOTSYS, PATH, LD_LIBRARY_PATH,
+DYLD_LIBRARY_PATH are configured correctly.
+
+Command to unpack the source code:
+
+   tar -zxf ExRootAnalysis.tar.gz
+
+Commands to create shared library for interactive ROOT session:
+
+   cd ExRootAnalysis
+
+   make
+
+Commands to create static library for linking with PGS:
+
+   cd ExRootAnalysis
+
+   make static
+
+
+
+
+Simple analysis using TTree::Draw
+=================================
+
+
+Now we can start ROOT and look at the data stored in the ROOT tree.
+
+Start ROOT and load shared library:
+
+   root
+   gSystem->Load("lib/libExRootAnalysis.so");
+
+Open ROOT tree file and do some basic analysis using Draw or TBrowser:
+
+   TFile::Open("pgs_events.root");
+   LHCO->Draw("Electron.PT");
+   TBrowser browser;
+
+Note 1: LHCO - tree name, it can be learnt e.g. from TBrowser
+
+Note 2: Electron - branch name; PT - variable (leaf) of this branch
+
+Complete description of all branches can be found in
+
+   ExRootAnalysis/doc/RootTreeDescription.html
+
+
+
+
+Macro-based analysis
+====================
+
+
+Analysis macro consists of histogram booking, event loop (histogram filling),
+histogram display
+
+Basic analysis macro:
+
+{
+  // Load shared library
+  gSystem->Load("lib/libExRootAnalysis.so");
+  gSystem->Load("libPhysics");
+
+  // Create chain of root trees
+  TChain chain("LHCO");
+  chain.Add("pgs_events.root");
+  
+  // Create object of class ExRootTreeReader
+  ExRootTreeReader *treeReader = new ExRootTreeReader(&chain);
+  Long64_t numberOfEntries = treeReader->GetEntries();
+  
+  // Get pointers to branches used in this analysis
+  TClonesArray *branchJet = treeReader->UseBranch("Jet");
+  TClonesArray *branchElectron = treeReader->UseBranch("Electron");
+  
+  // Book histograms
+  TH1 *histJetPT = new TH1F("jet_pt", "jet P_{T}", 100, 0.0, 100.0);
+  TH1 *histMass = new TH1F("mass", "M_{inv}(e_{1}, e_{2})", 100, 40.0, 140.0);
+
+  // Loop over all events
+  for(Int_t entry = 0; entry < numberOfEntries; ++entry) {
+
+    // Load selected branches with data from specified event
+    treeReader->ReadEntry(entry);
+  
+    // If event contains at least 1 jet
+    if(branchJet->GetEntries() > 0) {
+
+      // Take first jet
+      TRootJet *jet = (TRootJet*) branchJet->At(0);
+      
+      // Plot jet transverse momentum
+      histJetPT->Fill(jet->PT);
+      
+      // Print jet transverse momentum
+      cout << jet->PT << endl;
+    }
+
+    TRootElectron *elec1, *elec2;
+    TLorentzVector vec1, vec2;
+
+    // If event contains at least 2 electrons
+    if(branchElectron->GetEntries() > 1) {
+
+      // Take first two electrons
+      elec1 = (TRootElectron *) branchElectron->At(0);
+      elec2 = (TRootElectron *) branchElectron->At(1);
+
+      // Create two 4-vectors for the electrons
+      vec1.SetPtEtaPhiM(elec1->PT, elec1->Eta, elec1->Phi, 0.0);
+      vec2.SetPtEtaPhiM(elec2->PT, elec2->Eta, elec2->Phi, 0.0);
+
+      // Plot their invariant mass
+      histMass->Fill((vec1 + vec2).M());
+    }
+  }
+
+  // Show resulting histograms
+  histJetPT->Draw();
+  histMass->Draw();
+}
+
+
+
+
+More advanced macro-based analysis
+==================================
+
+
+ExRootAnalysis/test contains macro Example.C using class ExRootTreeReader to
+access data and class ExRootResult to manage histograms booking and output
+
+Here are commands to run this macro:
+
+   cd ExRootAnalysis/test
+   $EDITOR test.list
+   root
+   gSystem->Load("../lib/libExRootAnalysis.so");
+   .X Example.C("test.list");
+
+Note: file test.list should contain list of root files that you would like to
+analyse (one root file per line)
+
+
Index: trunk/doc/awk/branches_gen.awk
===================================================================
--- trunk/doc/awk/branches_gen.awk	(revision 4)
+++ trunk/doc/awk/branches_gen.awk	(revision 4)
@@ -0,0 +1,54 @@
+BEGIN {
+  print "<html>"
+  
+  print "<head>"
+  print "  <meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">"
+  print "  <meta NAME=\"keywords\" CONTENT=\"root, tree, ntuple, format, description\">"
+  print "  <title>root tree description</title>"
+  print "</head>"
+
+  print "<body>"
+  
+  print "<H1>root tree description</H1>"
+  print "<hr>"
+  print "<H2>Branches</H2>"
+  print "<hr>"
+
+  print "<table style=\"border: 1px dotted;\" align=\"center\" border=\"0\" cellpadding=\"7\" cellspacing=\"3\" widt=\"95%\">"
+  print "<tr><td><b>Branch</b></td>"
+  print "<td><b>Definition</b></td>"
+  print "<td><b>Class</b></td></tr>"
+
+  even = 1;
+  previous_line = ""
+}
+
+function print_line(previous_line, current_line, even) {
+  if(even) print "<tr bgcolor=\"#eeeeee\">"
+ 	else print "<tr bgcolor=\"#ffffff\">"
+  split(current_line, a, "\"");
+  print "  <td>"a[2]"</td>"
+  split(previous_line, a, "// ");
+  print "  <td>"a[2]"</td>"
+  split(current_line, a, ",");
+  split(a[2], b, "::");
+  gsub(" ", "", b[1]);
+ 
+  if(b[1] == "ExRootGen" || b[1] == "ExRootSimParticle") b[1] = "ExRootGenParticle";
+ 
+  print "  <td><a href=\"#"b[1]"\">"b[1]"</a></td>";
+  print "</tr>";
+}
+
+/NewBranch/ {
+  print_line(previous_line, $0, even);
+  even = !even;
+}
+
+{
+  previous_line = $0
+}
+
+END {
+  print "</table>"
+}
Index: trunk/doc/awk/classes_gen.awk
===================================================================
--- trunk/doc/awk/classes_gen.awk	(revision 4)
+++ trunk/doc/awk/classes_gen.awk	(revision 4)
@@ -0,0 +1,55 @@
+BEGIN {  
+  print "<hr>"
+  print "<H2>Classes</H2>"
+  print "<hr>"
+
+  print "<table style=\"border: 1px dotted;\" align=\"center\" border=\"0\" cellpadding=\"7\" cellspacing=\"3\" widt=\"95%\">"
+  print "<tr><td><b>Parameter</b></td>"
+  print "<td><b>Definition</b></td>"
+  print "<td><b>How it was calculated</b></td></tr>"
+
+}
+
+function print_line(name, comment, even, end) {
+  if(name != ""){
+   	if(even) print "<tr bgcolor=\"#eeeeee\">"
+   	else print "<tr bgcolor=\"#ffffff\">"
+    print "  <td>"name"</td>"
+    split(comment, a, "|");
+    print "  <td>"a[1]"</td>"
+    print "  <td>"a[2]"</td>"
+    print "</tr>"
+  }
+}
+
+/^ *class ExRoot/{
+  print_line(name, comment, even, 1);
+  even = 1;
+  name = "";
+  comment = "";
+  split($2, a, ":");
+  print "<tr bgcolor=\"#ffffff\"><td colspan=3><hr><a name=\""a[1]"\"><H3>"a[1]"</H3><hr></td></tr>"
+}
+
+/: public ExRoot[^S]/{
+  name = sprintf("<a href=\"#%s\">%s</a>", $4, $4);
+  split($2, a, ":");
+  comment = sprintf("%s inherits all %s parameters", a[1], $4);
+}
+
+/^ *[A-Za-z_]* [A-Za-z].*; \/\/ / {
+  print_line(name, comment, even, 0);
+  split($2, a, ";");
+  name = a[1];
+  split($0, a, "// ");
+  comment = a[2];
+  even = !even;
+}
+
+/^ +\/\/ /{split($0, a, "// "); comment = comment" "a[2]}
+END {
+  print_line(name, comment, even, 1);
+  print "</table>"
+  print "</body></html>"
+}
+
Index: trunk/doc/awk/script.sh
===================================================================
--- trunk/doc/awk/script.sh	(revision 4)
+++ trunk/doc/awk/script.sh	(revision 4)
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+if [ $# -ne 1 ]
+then
+  echo " Usage: $0 output_file"
+  echo " output_file - output file in HTML format."
+  exit
+fi
+
+awk -f branches_gen.awk \
+  ../../test/ExRootLHEFConverter.cpp \
+  ../../test/ExRootSTDHEPConverter.cpp \
+  ../../test/ExRootLHCOlympicsConverter.cpp > $1
+awk -f classes_gen.awk \
+  ../../ExRootAnalysis/ExRootClasses.h >> $1
+
Index: trunk/doc/awk/script_with_pgs.sh
===================================================================
--- trunk/doc/awk/script_with_pgs.sh	(revision 4)
+++ trunk/doc/awk/script_with_pgs.sh	(revision 4)
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+if [ $# -ne 1 ]
+then
+  echo " Usage: $0 output_file"
+  echo " output_file - output file in HTML format."
+  exit
+fi
+
+awk -f branches_gen.awk \
+  ../../test/ExRootLHEFConverter.cpp \
+  ../../pgs/ExRootAnalysis.cc > $1
+awk -f classes_gen.awk ../../ExRootAnalysis/ExRootClasses.h >> $1
+
Index: trunk/doc/epstosmth
===================================================================
--- trunk/doc/epstosmth	(revision 4)
+++ trunk/doc/epstosmth	(revision 4)
@@ -0,0 +1,335 @@
+#!/usr/bin/env perl
+
+# Copyright 1998-2001 by Sebastian Rahtz et al.
+# epstopdf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# epstopdf is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with epstopdf; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+use strict;
+
+# A script to transform an EPS file so that:
+#   a) it is guarenteed to start at the 0,0 coordinate
+#   b) it sets a page size exactly corresponding to the BoundingBox
+# This means that when Ghostscript renders it, the result needs no
+# cropping, and the PDF MediaBox is correct.
+#   c) the result is piped to Ghostscript and a PDF version written
+#
+# It needs a Level 2 PS interpreter.
+# If the bounding box is not right, of course, you have problems...
+#
+# The only thing I have not allowed for is the case of
+# "%%BoundingBox: (atend)", which is more complicated.
+#
+# Sebastian Rahtz, for Elsevier Science
+#
+# now with extra tricks from Hans Hagen's texutil.
+#
+# History
+#  1999/05/06 v2.5 (Heiko Oberdiek)
+#    * New options: --hires, --exact, --filter, --help.
+#    * Many cosmetics: title, usage, ...
+#    * New code for debug, warning, error
+#    * Detecting of cygwin perl
+#    * Scanning for %%{Hires,Exact,}BoundingBox.
+#    * Scanning only the header in order not to get a wrong
+#      BoundingBox of an included file.
+#    * (atend) supported.
+#    * uses strict; (earlier error detecting).
+#    * changed first comment from '%!PS' to '%!';
+#    * corrected (atend) pattern: '\s*\(atend\)'
+#    * using of $bbxpat in all BoundingBox cases,
+#      correct the first white space to '...Box:\s*$bb...'
+#    * corrected first line (one line instead of two before 'if 0;';
+#  2000/11/05 v2.6 (Heiko Oberdiek)
+#    * %%HiresBoundingBox corrected to %%HiResBoundingBox
+#  2001/03/05 v2.7 (Heiko Oberdiek)
+#    * Newline before grestore for the case that there is no
+#      whitespace at the end of the eps file.
+#  2006/05/09 v2.8 (David W. Rankin, Jr.)
+#    * option --pdfvers to specify the Ghostscript command to set
+#      the PDF version output.
+
+my $IsWin32 = ($^O =~ /MSWin32/i);
+
+### program identification
+my $program = "epstosmth";
+my $filedate="2006/05/09";
+my $fileversion="2.8";
+my $copyright = "Copyright 1998-2001 by Sebastian Rahtz et al.";
+my $title = "\U$program\E $fileversion, $filedate - $copyright\n";
+
+### ghostscript command name
+my $GS = "gs";
+$GS = "gswin32c" if $^O eq 'MSWin32';
+
+if ($IsWin32) {
+  $GS = `kpsecheck --ghostscript`;
+  $GS =~ m/^dll\s*:\s*(.+)/mio;
+  $GS = $1;
+  $GS =~ s/gsdll32.dll/gswin32c.exe/io;
+  if ($GS eq "") {
+    $GS = "gswin32c.exe";
+  }
+  $GS = "\"$GS\"" if ($GS =~ m/\s/);
+}
+
+### options
+$::opt_help=0;
+$::opt_debug=0;
+$::opt_compress=1;
+$::opt_gs=1;
+$::opt_hires=0;
+$::opt_exact=0;
+$::opt_filter=0;
+$::opt_outfile="";
+$::opt_pdfvers="";
+$::opt_gsdev="pdfwrite";
+$::opt_gsopt="";
+
+### usage
+my @bool = ("false", "true");
+my $usage = <<"END_OF_USAGE";
+${title}Syntax:  $program [options] <eps file>
+Options:
+  --help:           print usage
+  --outfile=<file>: write result to <file>
+  --(no)filter:     read standard input    (default: $bool[$::opt_filter])
+  --(no)gs:         run ghostscript        (default: $bool[$::opt_gs])
+  --(no)compress:   use compression        (default: $bool[$::opt_compress])
+  --(no)pdfvers:    PDF Version for Output (default: [GhostScript's default])
+  --(no)hires:      scan HiResBoundingBox  (default: $bool[$::opt_hires])
+  --(no)exact:      scan ExactBoundingBox  (default: $bool[$::opt_exact])
+  --(no)debug:      debug informations     (default: $bool[$::opt_debug])
+  --gsdev=<dev>:    select gs device
+  --gsopt=<opts>:   additional gs options
+Examples for producing 'test.pdf':
+  * $program test.eps
+  * produce postscript | $program --filter >test.pdf
+  * produce postscript | $program -f -d -o=test.pdf
+Example: look for HiResBoundingBox and produce corrected PostScript:
+  * $program -d --nogs -hires test.ps>testcorr.ps
+END_OF_USAGE
+
+### process options
+use Getopt::Long;
+GetOptions (
+  "help!",
+  "debug!",
+  "filter!",
+  "compress!",
+  "gs!",
+  "hires!",
+  "exact!",
+  "pdfvers=s",
+  "outfile=s",
+  "gsdev=s",
+  "gsopt=s",
+) or die $usage;
+
+### help functions
+sub debug {
+  print STDERR "* @_\n" if $::opt_debug;
+}
+sub warning {
+  print STDERR "==> Warning: @_!\n";
+}
+sub error {
+  die "$title!!! Error: @_!\n";
+}
+sub errorUsage {
+  die "$usage\n!!! Error: @_!\n";
+}
+
+### option help
+die $usage if $::opt_help;
+
+### get input filename
+my $InputFilename = "";
+if ($::opt_filter) {
+  @ARGV == 0 or
+    die errorUsage "Input file cannot be used with filter option";
+  $InputFilename = "-";
+  debug "Input file: standard input";
+}
+else {
+  @ARGV > 0 or die errorUsage "Input filename missing";
+  @ARGV < 2 or die errorUsage "Unknown option or too many input files";
+  $InputFilename = $ARGV[0];
+  -f $InputFilename or error "'$InputFilename' does not exist";
+  debug "Input filename:", $InputFilename;
+}
+
+### option compress
+my $GSOPTS = "$::opt_gsopt ";
+
+debug "gs opts:", $GSOPTS;
+
+$GSOPTS .= "-dUseFlateCompression=false " unless $::opt_compress;
+
+### option pdfvers (GhostScript PDF Compatability options)
+$GSOPTS .= "-dCompatibilityLevel=$::opt_pdfvers " unless $::opt_pdfvers eq "";
+
+### option BoundingBox types
+my $BBName = "%%BoundingBox:";
+!($::opt_hires and $::opt_exact) or
+  error "Options --hires and --exact cannot be used together";
+$BBName = "%%HiResBoundingBox:" if $::opt_hires;
+$BBName = "%%ExactBoundingBox:" if $::opt_exact;
+debug "BoundingBox comment:", $BBName;
+
+### option outfile
+my $OutputFilename = $::opt_outfile;
+if ($OutputFilename eq "") {
+  if ($::opt_gs) {
+    $OutputFilename = $InputFilename;
+    if (!$::opt_filter) {
+      $OutputFilename =~ s/\.[^\.]*$//;
+      if ($::opt_gsdev =~ m/^pdf/) {
+        $OutputFilename .= '.pdf';
+      } elsif ($::opt_gsdev =~ m/^png/) {
+        $OutputFilename .= '.png';
+      } elsif ($::opt_gsdev =~ m/^jpeg/) {
+        $OutputFilename .= '.jpg';
+      } else {
+        $OutputFilename .= ($::opt_gsdev eq "" ? ".pdf" : ".$::opt_gsdev");
+      }
+    }
+  }
+  else {
+    $OutputFilename = "-"; # standard output
+  }
+}
+if ($::opt_filter) {
+  debug "Output file: standard output";
+}
+else {
+  debug "Output filename:", $OutputFilename;
+}
+
+### option gs
+if ($::opt_gs) {
+  debug "Ghostscript command:", $GS;
+  debug "Compression:", ($::opt_compress) ? "on" : "off";
+}
+
+### open input file
+open(IN,"<$InputFilename") or error "Cannot open",
+  ($::opt_filter) ? "standard input" : "'$InputFilename'";
+binmode IN;
+
+### open output file
+if ($::opt_gs) {
+  my $pipe = "$GS -q -sDEVICE=$::opt_gsdev $GSOPTS " .
+          "-sOutputFile=$OutputFilename - -c quit";
+  debug "Ghostscript pipe:", $pipe;
+  open(OUT,"|$pipe") or error "Cannot open Ghostscript for piped input";
+}
+else {
+  open(OUT,">$OutputFilename") or error "Cannot write '$OutputFilename";
+}
+
+### scan first line
+my $header = 0;
+$_ = <IN>;
+if (/%!/) {
+  # throw away binary junk before %!
+  s/(.*)%!/%!/o;
+}
+$header = 1 if /^%/;
+debug "Scanning header for BoundingBox";
+print OUT;
+
+### variables and pattern for BoundingBox search
+my $bbxpatt = '[0-9eE\.\-]';
+               # protect backslashes: "\\" gets '\'
+my $BBValues = "\\s*($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)\\s+($bbxpatt+)";
+my $BBCorrected = 0;
+
+sub CorrectBoundingBox {
+  my ($llx, $lly, $urx, $ury) = @_;
+  debug "Old BoundingBox:", $llx, $lly, $urx, $ury;
+  my ($width, $height) = ($urx - $llx, $ury - $lly);
+  my ($xoffset, $yoffset) = (-$llx, -$lly);
+  debug "New BoundingBox: 0 0", $width, $height;
+  debug "Offset:", $xoffset, $yoffset;
+
+  print OUT "%%BoundingBox: 0 0 $width $height\n";
+  print OUT "<< /PageSize [$width $height] >> setpagedevice\n";
+  print OUT "gsave $xoffset $yoffset translate\n";
+}
+
+### scan header
+if ($header) {
+  while (<IN>) {
+
+    ### end of header
+    if (!/^%/ or /^%%EndComments/) {
+      print OUT;
+      last;
+    }
+
+    ### BoundingBox with values
+    if (/^$BBName$BBValues/) {
+      CorrectBoundingBox $1, $2, $3, $4;
+      $BBCorrected = 1;
+      last;
+    }
+
+    ### BoundingBox with (atend)
+    if (/^$BBName\s*\(atend\)/) {
+      debug $BBName, "(atend)";
+      if ($::opt_filter) {
+        warning "Cannot look for BoundingBox in the trailer",
+                "with option --filter";
+        last;
+      }
+      my $pos = tell(IN);
+      debug "Current file position:", $pos;
+
+      # looking for %%BoundingBox
+      while (<IN>) {
+        # skip over included documents
+        if (/^%%BeginDocument/) {
+          while (<IN>) {
+            last if /^%%EndDocument/;
+          }
+        }
+        if (/^$BBName$BBValues/) {
+          CorrectBoundingBox $1, $2, $3, $4;
+          $BBCorrected = 1;
+          last;
+        }
+      }
+
+      # go back
+      seek(IN, $pos, 0) or error "Cannot go back to line '$BBName (atend)'";
+      last;
+    }
+
+    # print header line
+    print OUT;
+  }
+}
+
+### print rest of file
+while (<IN>) {
+  print OUT;
+}
+
+### close files
+close(IN);
+print OUT "\ngrestore\n" if $BBCorrected;
+close(OUT);
+warning "BoundingBox not found" unless $BBCorrected;
+debug "Ready.";
+;
