Comparison of ZOOM PhysicsVectors Package and (April 1998) CLHEP Vector Sub-Package These pacvkages cover similar functions; this note will contrast features present in one or the other. We also point out differences in treatment which might be considered a plus or minus for either side. We omit things which are either purely cosmetic (slight differences in naming choices). A CLHEP compatability header, meant to allow code using CLHEP Vectors classes to run via the ZOOM package, unchanged except for substituting #include CLHEP_Vec.h, is being prepared. Also, a "notation convenience" header PhysVec.h is being prepared. Any differences which go away once these are present will be indicated by the symbol @. Some methods in CLHEP are mathematically ambiguous on the face of it, but use arbitrary subtle assumptions and references to make them sensible. These are driven by opertions convenient to Geant4. We will point out these differences as GEANT4 rather than as a usual feature difference. - - - - - - Each package has four fundamental sorts of objects: 3- and 4-vectors and 3D and 4D transformations. These are listed here, along with closely related classes. Hep3Vector SpaceVector (UnitVector) HepLorentzVector LorentzVector HepRotation Rotation (RotationX, RotationY, RotationZ) HepLorentzRotation LorentzTransformation (LorentzBoost, LorentzBoostX, LorentzBoostY, LorentzBoostZ) We will use v for a 3-vector, w for a 4-vector, R for a rotation, and T for a Lorentz transformation in these illustrations/ - - - - - - 1. Component access -------------------- The PhysicsVectors package has the following attitude about components specifying a vector or transformation: a) There may be several forms of components, that is, ways to specify a vector; for example, Cartesian vs Spherical coordinates. b) For each form of components, the package provides the obvious means of constructing and setting supplying all three components, and of getting individual components. c) Also, for each form of components, the package provides a way to change any one of the components, keeping the remaining ones constant. d) Although explicit get and set methods are provided, the packas also provides access operators that can be used on either side of an assignment, as in v.x() = 7.5. The Vector package provides a slightly slimmer variety of component forms, and does not support changing indiviual components in a given form. The specific differences are: PhysicsVectors CLHEP Vector -------------- ------------ == Accessor mechanism == + v.x() = whatever; or also v.setX(whatever) v.setX(whatever) only + w.x() = whatever; + v.x() += whatever; and so forth + v.r() = whatever; + v.phi() = whatever; + v.theta() = whatever; + p = v.r() along with p=v.mag() v.mag() only - v(j) components by index == Cylindrical coordinates == + p = v.rho(); + v.rho() = whatever; + setCylTheta(theta): keeping rho, phi fixed. == PseudoRapidity substituting for theta == + p = v.eta(); Comment: This is a big one; users work with eta along the Z axis rather that theta very often. + v.eta() = whatever; keeping r and phi fixed + v.setCylEta keeping rho and phi fixed PhysicsVectors CLHEP Vector -------------- ------------ == Rotation in terms of axis/delta and in terms of EulerAngles == + Rotation(axis, delta) - rotate(axis, delta) does a further rotation around this new axis; related to multiplication. + p = R.axis() + p = R.delta() + R.axis() = whatever; + R.delta() = whatever; + R.delta()+= whatever; + R.delta()*= whatever; e.g R.delta -= 1 + R ( phi, theta, psi ); + p = R.psi() and R.psi() = whatever; + p = R.theta() and R.theta() = whatever; + p = R.phi() and R.phi() = whatever; == Rows and colums == + u = R.rowX() u = R.rowY(); u = R.rowZ(); Comment: One note about a major performance hit in a CLHEP-using code was because they were extracting rows by multiplying by unit coordinate vectors. This would make such a happening unlikely! + w = T.row1(); w=T.row2(); w = T.row3(); w=T.row4(); - Constructor from 3 rows RotateAxes from 3 columns Comment: The choice of specifying rows rather than columns was the wrong choice; columns represent the new axes and that is more often useful to a physicist. This change will be made. It will be better to have a constructor taking 3 columns, than the rotateAxes method. + T.row1() T.row2() T.row3() T.row4() (also columns) for LorentzTransformation + Constructor of T from 4 columns. + R.ZMpvRep3x3() + T.ZMpvRep4x4() for all 9 or 16 elements in one chunk 2. Specialized Classes There are minor concpetual advantages, and at times substatntial efficiency advantages, to classes for UnitVector, pure boost, and coordinate axis rotations and boosts. There are aslo some side consequences. PhysicsVectors CLHEP Vector -------------- ------------ + UnitVector Comment: Whenever a refernece direction is needed, the fore-knowledge that this need not be normalized is a major performance edge. @ UnitVector(v) v.unit() X_HAT, Y_HAT, Z_HAT HepXhat, HepYhat, HepZhat known to be unit vecotrs + RotationX + RotationY + RotationZ + LorentzBoost + LorentzBoostX + LorentzBoostY + LorentzBoostZ Comment: These are important both in terms of stroage and when applying a transformation to a vector or 4-vector. + Rotation::IDENTITY + LorentzTransfomration::IDENTITY 3. Nearness and distance metrics Because comparisons are often meaningful only within some precision (dictated either be accuracy of data input or by round-off error), the PhysicsVectors class provides boolean isNear() methods, with default or user-specified tolerances. In the same vein, the package supplies the raw "distance" measure, which the user can cut on, plot, or whatever. PhysicsVectors CLHEP Vector -------------- ------------ + v.isNear(v2) + v.howNear(v2) + v.deltaR(v2) Comment: This has been requested by quite a few people from CDF and D0 independantly. Though deltaR sounds peculiar to me, both experiments use the same term for the same concept so it is clear to the people who will matter. deltaR = sqrt(delta_eta**2 + delta_phi**2) + v.isParallel(v2) + v.howParallel(v2) + v.isOrthogonal(v2) + v.howOrthogonal(v2) + w.isNear(w2) + w.howNear(w2) + w.isNearCM(w2) + w.howNearCM(w2) Comment: Lorentz invariant measures of nearness in CM frame; these are applicable only to timelike 4-vectors. + w.deltaR(w2) + w.delta2Euclidean(w2) + w.isSpacelike() + w.isTimelike() + w.isLightlike() + w.howLightlike() + w.isParallel(w2) + w.howParallel(w2) 4. Methods on 3-vectors The PhysicsVectors class provides a variety of methods acting on 3-vectors. The primary extensions relative to the CLHEP classes are that many methods which have an implied Z reference direction also have forms (in SpaceVector) taking an arbitrary reference direction. The PhysicsVectors package also has rapidity and angle decomposition methods. PhysicsVectors CLHEP Vector -------------- ------------ v.perp2() v.perp() v.perp2() v.perp() + v.perp2(u) v.perp(u) + v.perpPart() v.perpPart(u) + v.project() v.project(u) + v.polarAngle(u) + v.azimAngle(u) Comment: Angle decomposition methods stemmed from a discussion with Marc Paterno. + v.rotate(Euler angles) + v/scalar + unary minus on vectors and 4-vectors + v.rapidity v.rapidity(u) + v.colinearRapidity() v.angle(u) v.angle(v) + v.cosTheta(u) There are some methods in HepVector that are specific for the convenience of Geant4. These are mathematically unnatural or contain hidden assumptions in their definitions. Nonetheless, the CLHEP_Vec.h header will support these, as they must be useful to the Geant4 crowd. PhysicsVectors CLHEP Vector -------------- ------------ GEANT4 v.orthogonal() returns a vector orthogonal to v; the choice is contrived GEANT4 R.rotateUz() Rotates axes so that the Z axis is along some new vector. The choice among the set of such rotations is contrived 5. Operator overloading of * and application of rotations It was agreed that PhysicsVectors would not overload * to mean dot product and application of rotations. It was felt that ambiguities in meaning would be present if we did. However, this convenient notation is popular enough that it will be supported via PhysVec.h PhysicsVectors CLHEP Vector -------------- ------------ @ v1.dot(v2) v1 * v2 or v1.dot(w2) @ w1.dot(w2) w1 * w2 or w1.dot(w2) @ R(v) R*v Comment: The "apply" syntax makes more sense mathematically but since physicists think of a rotation in terms of its matrix representation, the natural looking R*v will be in PhysVec.h R(v) v.transform(R) Comment: This is a serious design difference. In the PhysicsVectors package, SpaceVector is at a "lower" level then Rotation, and the class does not know about Rotation at all -- direct rotations are expressed in terms of EulerAngles or axis and delta. So if Rotations as objects in their own right are not part of the user's task, he need not pull in the Rotation class. In consequence, however, there can be no method of SpaceVector that works with a Rotation argument. 6. 4-Vector methods The PhysicsVectors package has more kinematics methods, and can work with containers of LorentzVectors. PhysicsVectors CLHEP Vector -------------- ------------ + setMetric() Comment: At the January workshop, it was indicated that the desired metric was (+ + + -). CLHEP uses (- - - +) which in many ways is much more convenient. To resolve this, PhysicsVectors defaults to the CLHEP standard, but allows the user to change to TimeNegative. w(j) components by index w.plus() w.minus() w.plus() w.minus() + w.plus(u) w.minus(u) + w.eta() w.eta(u) + w.rapidity() w.colinearRapidity() + restVector() + invariantMass (Container) + findBoostToCM (Container) + applyBoostToCM(Container) HepLorentzVectors have more convenient notation for working with their 3-vector parts. These are obviously provided as a remnant of the 4-vector inheriting from 3-vector: The methods would have worked then, so they must work now. PhysicsVectors could be extended to include those notations if desired but since there are many more 3-vector methods available, it is more work. PhysicsVectors CLHEP Vector -------------- ------------ - w.getV().phi() w.phi() - w.getV().theta() w.phi() - w.getV().r() w.rho() Note naming differnece: with no cylindrical coordinates, using rho for radius is sensible. - w.getV().perp() or w.z() w.perp() - w.getV().perp2(v) w.perp2(v) - w.getV().angle(v) w.angle(v) w.v() HepThreeVector(w) Comment: The cast to a 3-vector, dropping the t component, is potentially trappy and confusiing. But again, it is needed for back compatibility with the inheritance days. - w.px() w.py() w.pz() w.E() w.x() w.y() w.z() w.t() w.x() w.y() w.z() w.t() Several differences reflect a matter of taste: PhysicsVectors CLHEP Vector -------------- ------------ T(w) w.transform(T) w.invariantMass2() w.m2() w.invariantMass() w.m() w.findBoostToCM() w.boostVector() LorentzVector(x,y,z,Tcomponent(t)) HepLorentzVector(x,y,z,t) LorentzVector(Tcomponent(t),x,y,z) Comment: The convenience of not haveing to specify which is the T component, versus the trap of not catching the error of supplying (t,x,y,z). 7. Treatment of Rotations and Lorentz Transformations PhysicsVectors CLHEP Vector -------------- ------------ + rectify() In case a long series of operations might accumulate round-off error + w = r*w v = R*w Comment: The application of a Rotation to HepLorentzVector in CLHEP yields a 3-vector, dropping the t component. THis is plain wrong. - R(i,j) - T(i,j) components by index (R == Rotation::IDENTITY) R.isIdentity() - R.transform(R2) left-multiplication analog of *= that is, R = R2*R inverseOf(R) R.inverse() + T.decompose(B, R) + T.decompose(R, B) + LorentzBoost b.direction() + b.beta() + b.gamma() + R(Container) + R(Container) + T(Container) GEANT4 R.phiX() const; GEANT4 R.phiY() const; GEANT4 R.phiZ() const; GEANT4 R.thetaX() const; GEANT4 R.thetaY() const; GEANT4 R.thetaZ() const; Comment: Angles made by rotated axes against the originals; Mathematically needs one more piece of info for phi to be well defined. 8. Sorting comparisons Each data type in PhysicsVector contains "dictionary ordering" coparison operators so that one can form a standard container of that class and use all the various sort and search algorithms. HepVector, having been created before standard containers were sensible to use, saw no need for these. PhysicsVectors CLHEP Vector -------------- ------------ + operator > operator < + operator >= operator <=