Rotating vectors with ROOT::Math::XYZVector

When trying to convert code originally written for Geant4, I came across the following lines:

 G4ThreeVector v(m_Distance*sinTheta*cos(phi),
                 m_Distance*sinTheta*sin(phi),
                 m_Distance*cosTheta);
 v.rotateUz(-m_CenterDirection);

I’m converting this code to run in ROOT. My first inclination was to use TVector3D, since it also has a rotateUz method like G4ThreeVector (which is a CLHEP::Hep3Vector).

But at the top of the TVector3D page, it states:

TVector3 is a legacy class. It is slower and worse for serialization than the recommended superior alternative ROOT::Math::XYZVector.

When I follow the links through ROOT::Math::XYZVector to ROOT::Math::DisplacementVector3D, I see that this recommended new vector class doesn’t have any rotation methods, much less rotateUz.

In this new paradigm, what approach is one supposed to use for rotating vectors, rotateUz in particular? I see the ROOT::Math::VectorUtil and ROOT::Math::AxisAngle classes, but I am not facile with vector rotations; I don’t get which methods might correspond to rotateUz (if indeed any of them do).

Or should I simply stick to TVector3D?


ROOT Version: 6.22
Platform: CentOS 7
Compiler: GCC 10.2


Hi @seligman ,
I think you want ROOT: ROOT::Math::VectorUtil Namespace Reference , the RotateZ free function that you can call as RotateZ(vector, angle).

Cheers,
Enrico

I saw that. The problem for lazy 'ol me is: TVector3D::RotateUz effectively takes as arguments two vectors, the second of which is a unit vector pointing in the new direction of the z-axis (I think; the documentation is unclear). VectorUtil::RotateZ take as arguments a vector and an angle; that second angle is simply a rotation about the z-axis. I don’t know how to connect one to the other.

Ah I see, I am not sure either. We need @moneta 's help here – but please consider that things might be slower over the holidays.

Cheers,
Enrico

No problem; I’m not in a rush. For now, I’ve worked around the problem by copying the TVector3D::RotateUz code into a separate function, using ROOT::Math::XYZVector arguments.

Of course, just to make life interesting, I see that the code for RotateUz in TVector3D and CLHEP::ThreeVector is not the same. If I were more motivated, I’d go through the trig identifies to verify that the methods have identical functionality. Or maybe they don’t…

Hi,

I am not sure exactly what TVector3::RotateUz does, for CLHEP from the documentation I see that is equivalent first to a rotation along the Y axis of an angle theta followed by a rotation along the Z axis by an angle phi.
Given the direction (u1,u2,u3), the angle theta should be such theta = acos(u3) and
phi = atan(u2/u1). You can then use the ROOT::Math::RotationZYX class using an angle 0 for psi (rotation along X)

Cheers

Lorenzo

In the end, I chickened out and went with TVector3D. There were other functions like “orthogonal” that were just not clear in the XYZVector / VecUtil mechanism. My poor python-addled brain couldn’t figure it all out.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.